2

SCENARIO

I am having 2 fragments inside a View Pager. In one of the fragment I am having a button to generate notification. Notification is generated successfully. Now I want to send some data on notification click back to fragment. For this I am using onNewIntent() method inside activity and from that I called fragment method to pass data back to the fragment.

All this is working fine.

PROBLEM:

After receiving data from notification I am adding it to an arraylist and showing it in RecyclerView. Now main problem is that in this scenario onCreateView() is not called again and due to this issue all the views in the fragment are null which is causing Null Pointer Exception all the time. Is there any way to get view in onResume() or save reference to previous views.

Here is the related code.

Activity onNewIntent() code:

@Override
protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
    intent=getIntent();
    if (intent.hasExtra("notification_data")) {
        Record record = (Record) intent.getSerializableExtra("notification_data");
        FragmentRecords fragmentRecords = new FragmentRecords();
        fragmentRecords.getDataFromIntent(record);
    }

}

Fragment getDataFromIntent method:

    public void getDataFromIntent(Record record){

       DatabaseManager databaseManager=new DatabaseManager(MainActivity.context);
       recordDao = null;
       try {
           recordDao=databaseManager.getDao();
           addData();
       } catch (SQLException e) {
           e.printStackTrace();
       }
       recordArrayList.add(record);
       recordAdapter.notifyDataSetChanged();
   }

initView() method

private void initView(View view){
    btnAddRecords= (Button) view.findViewById(R.id.btn_add_data);
    btnNotification= (Button) view.findViewById(R.id.btn_create_notification);
    recyclerRecords= (RecyclerView) view.findViewById(R.id.rv_list);
    recordArrayList=new ArrayList<>();
    DatabaseManager databaseManager=new DatabaseManager(MainActivity.context);
    recordDao = null;
    try {
        recordDao=databaseManager.getDao();
        addData();
    } catch (Exception e) {
        e.printStackTrace();
    }

addData() method consists of adding static data into the arraylist.

private void addData(){
    recordArrayList.add(new Record("Ram","1234567890","10 years","hello",1L));
    recordArrayList.add(new Record("Rahim","1234567890","12 years","hello",2L));
    recordArrayList.add(new Record("Shyam","1234567890","13 years","hello",3L));
    recordArrayList.add(new Record("Sunder","1234567890","40 years","hello",4L));
    recordArrayList.add(new Record("Demo","1234567890","14 years","hello",5L));
    recordArrayList.add(new Record("Demo1","1234567890","15 years","hello",6L));
    recordArrayList.add(new Record("Demo2","1234567890","16 years","hello",7L));
    for (int i=0;i<recordArrayList.size();i++){
        try {
            recordDao.create(recordArrayList.get(i));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    Toast.makeText(MainActivity.context, recordArrayList.size()+" records added successfully", Toast.LENGTH_SHORT).show();
   setAdapter();
}


private void setAdapter(){
       recordAdapter=new RecordAdapter(MainActivity.context,recordArrayList);
       RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(MainActivity.context);
       recyclerRecords.setLayoutManager(mLayoutManager);
       recyclerRecords.setItemAnimator(new DefaultItemAnimator());
       recyclerRecords.addItemDecoration(new SimpleItemDecorator(5));
       recyclerRecords.setAdapter(recordAdapter);


   }

Error Stacktrace

java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v7.widget.RecyclerView.setLayoutManager(android.support.v7.widget.RecyclerView$LayoutManager)' on a null object reference at com.testdemo.fragments.FragmentRecords.setAdapter(FragmentRecords.java:134) at com.testdemo.fragments.FragmentRecords.addData(FragmentRecords.java:128) at com.testdemo.fragments.FragmentRecords.getDataFromIntent(FragmentRecords.java:148) at com.testdemo.activities.MainActivity.onNewIntent(MainActivity.java:52) at android.app.Instrumentation.callActivityOnNewIntent(Instrumentation.java:1265) at android.app.Instrumentation.callActivityOnNewIntent(Instrumentation.java:1282) at android.app.ActivityThread.deliverNewIntents(ActivityThread.java:2755) at android.app.ActivityThread.performNewIntents(ActivityThread.java:2773) at android.app.ActivityThread.handleNewIntent(ActivityThread.java:2782) at android.app.ActivityThread.-wrap12(ActivityThread.java) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1602) at android.os.Handler.dispatchMessage(Handler.java:111) at android.os.Looper.loop(Looper.java:227) at android.app.ActivityThread.main(ActivityThread.java:6102) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:961) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:822)

Vivek Mishra
  • 5,669
  • 9
  • 46
  • 84
  • Can you post the error stacktrace? – Juan Martinez Feb 23 '17 at 13:18
  • error is null pointer as it is not calling onCreateView therefore when it moves to setAdapter method recyclerview is null therefore it crashes – Vivek Mishra Feb 23 '17 at 13:19
  • In onNewIntent you are creating new intent of FragmentRecords and calling getDataFromIntent function on a completely new object. – nnn Feb 23 '17 at 13:24
  • That's true, you're interacting with a new fragment that isn't started yet, that's the reason for the null pointer exception. – Juan Martinez Feb 23 '17 at 13:30
  • how to solve it then?? – Vivek Mishra Feb 23 '17 at 13:31
  • but if it is a new fragment then onCreateView must be called in my opinion – Vivek Mishra Feb 23 '17 at 13:41
  • You might be able to simplify matters by integrating EventBus. It can be used to notify the fragment of newly created items in a more decoupled fashion (without the need to use Activity in between). That is, it only listens for events while it is available, hence no nullpointer exception. Just a suggestion. – cYrixmorten Feb 23 '17 at 13:47
  • @cYrixmorten I would love to do it but this was just a demo project and problem was solved by keeping single instance of the fragment – Vivek Mishra Feb 23 '17 at 13:53
  • @VivekMishra Alright :) as long as you found a working solution – cYrixmorten Feb 23 '17 at 14:00

1 Answers1

1

As it was pointed out on the comments, you are interacting with a new FragmentRecords instance which isn't started yet instead of using your existing fragment. You should try to retrieve a reference to the existing FragmentRecords instance (maybe through findFragmentByTag method if you are using tags to identify your fragments) and then call the getDataFromIntent on that instance.

I hope it helps.

Juan Martinez
  • 770
  • 5
  • 16