NullPointer when calling Fragment method from activity

gkiko

I've been struggling with this error since the last week. Here it is:

public class MainActivity extends FragmentActivity implements ActionBar.TabListener {
    AppSectionsPagerAdapter mAppSectionsPagerAdapter;
    ViewPager mViewPager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mAppSectionsPagerAdapter = new AppSectionsPagerAdapter(getSupportFragmentManager(), getApplicationContext());
        mViewPager = (ViewPager) findViewById(R.id.pager);
        mViewPager.setAdapter(mAppSectionsPagerAdapter);
        ...
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle item selection
        switch (item.getItemId()) {
        case R.id.refresh:
            mAppSectionsPagerAdapter.onRefresh();
            return true;
        ...
    }


public class AppSectionsPagerAdapter extends FragmentPagerAdapter {
    private ArrayList<Fragment> fragmentList;
    private MainSectionFragment f1, f2;
    private SelectedSectionFragment f3;

    public AppSectionsPagerAdapter(FragmentManager fm, Context c) {
        f3 = new SelectedSectionFragment();
        f2 = new MainSectionFragment();
        f1 = new MainSectionFragment();

        fragmentList = new ArrayList<Fragment>();
        fragmentList.add(f1);
        fragmentList.add(f2);
        fragmentList.add(f3);
        ...
    }

    public void onRefresh(){
        MainSectionFragment fragment = (MainSectionFragment)fragmentList.get(0);
        fragment.fetchList();
    }
    ...
}

public class MainSectionFragment extends Fragment implements CallbackListener {
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        //some initialization
        c = getActivity().getApplicationContext(); // tested and it gets initialized
        System.out.println(""+hashCode());
        ...
    }

    void fetchList() {
        System.out.println(""+hashCode());
        android.support.v4.app.FragmentManager manager = getActivity().getSupportFragmentManager();
        ...
    }
}

description

I navigate from ActivityMain and it dies. When I get back the list is scrollable vertically and horizontally. If I click refresh button NullPointerException arises. I've debugged the program. OnCreateView() is called when I return from SettingsActivity, but when I click refresh button, every field of MainSectionFragment becomes null.

Printed hashcodes before exception:

05-25 01:54:37.190: I/System.out(5982): 1091848056 //onCreateView()
05-25 01:54:42.680: I/System.out(5982): 1091574888 //fetchList()

Can't understand why are these objects different.

Let me know if my question is not clear.

UPDATE 1

I have checked 'Don't keep activities' option in dev tools. I have verified that MainActivitys onCreate is called after going back from SettingsActivity

UPDATE 2

Going to SettingsActivity detaches the fragments. Returning from SettingsActivity attaches the fragments again.

Budius

edit:

Even though the original answer got pretty close to answering properly, I wanted to edit to bring some knowledge to the case.

The Fragment stack works (under a certain point of view) very similarly to the activity. As fragments are also automatically destroyed and re-created by the framework and have their state saved via the Bundles that get passed around the callbacks (savedInstanceState).

So what's happening is that even though, the activity is being re-created and a new Adapter being called, when supplying Fragments to the ViewPager the adapter first calls findFragmentByTag to the FragmentManager so that the saved states can be re-created, and it only calls public Fragment getItem(int position) if there's none.

So the fragments that you see on the screen are not the objects that were created during AppSectionsPagerAdapter constructor. Those fragments were never used.

Remember that, even though it sounds odd at first sight, that is a very desirable feature. For example: imagine there's an EditText on the fragment and the user filled it with some text. When the fragments gets destroyed, that value will be saved on the Bundle, and when restored the value is still there.

original answer:

"Can't understand why are these objects different." because that's how the framework operates. Fragments are objects that can be destroyed/re-created by the Framework.

99% chances of what is happening is:

  • MainActivity.onCreate.onStart.onResume
  • MainSectionFragment.onCreateView.onResume
  • then it goes to Settings:
  • MainSectionFragment.onPause.onDestroyView <<< destroys the view
  • MainActivity.onPause.onStop
  • when you back from the settings
  • MainActivity.onStart.onResume <<< it doesn't call onCreate, it was never destroyed.
  • the framework re-creates your fragment automatically
  • MainSectionFragment(new instance).onCreateView.onResume
  • you click on the refresh button
  • MainActivity call the old MainSectionFragment. The MainSectionFragment that the view was already destroyed.

The most direct (and cleaner) way to fix your code will be to make the Fragment handle the menu, simply simple put this in the fragment code, and remove the menu stuff from the activity:

onCreate(Bundle savedInstance){
   setHasOptionsMenu(true);
}

onOptionsItemSelected(MenuItem item){
   if(item.getItemId() == R.id.refresh){
      .. do your stuff here
      return true;
   } else return super.refresh(item);
}

If for some reason that you did not explain you really really must handle the menu in the activity there're other options:

For example: you could send a LocalBroadcast from the activity and have the fragment register/unregister a BroadcastReceiver during onResume/onPause

Or another nice trick: the FragmentPagerAdater uses the following method to create fragment TAG for the FragmentManager:

private static String makeFragmentName(int viewId, long id) {
   return "android:switcher:" + viewId + ":" + id;
}

so then you can add this to your activity and call:

 (MainSectionFragment)getSupportFragmentManager().
     findFragmentByTag(
         makeFragmentName(R.id.pager, mAppSectionsPagerAdapter.getItemId(0)))
           .fetchList();

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

NullPointerException when calling a Fragment method from Activity?

From Dev

NullPointer Exception when calling a method from onResume

From

Calling a Fragment method from a parent Activity

From Dev

calling parent activity method from fragment

From Dev

Calling fragment method from activity Android

From Dev

App Crashing when calling a Fragment from an Activity

From Java

Calling a function when an activity is returned to from fragment

From Dev

Calling Activity from Fragment

From Dev

Calling fragment from activity

From Dev

Calling Fragment method from Activity,findFragmentById returns null

From Dev

Calling Fragment's method from Activity doesn't work?

From Dev

Calling Activity method inside Fragment that is not attached to Activity

From Dev

NullPointer exception while passing a value from activity to Interface method and retrieve in fragment android

From Dev

Calling a custom fragment from an activity

From Dev

calling an activity from fragment activity through Intent

From Dev

calling fragment method in Activity not working kotlin

From

Call an activity method from a fragment

From Dev

Fragment method not accessible from Activity

From Dev

Call Fragment method from Activity

From Dev

Calling a fragment method from an Adapter

From Dev

Calling method from Fragment in ViewPager

From Dev

Calling a Fragment method from a singleton

From Dev

Call method in fragment from another fragment/activity

From Dev

Calling Activity method from FirebaseMessagingService

From Dev

Calling a method from Activity in Adapter

From Dev

Calling a method from an exported activity

From Dev

Calling method of activity from asynctask

From Dev

Navigate back to calling Fragment from another activity

From Dev

Calling Fragment from an activity and updating layout

Related Related

  1. 1

    NullPointerException when calling a Fragment method from Activity?

  2. 2

    NullPointer Exception when calling a method from onResume

  3. 3

    Calling a Fragment method from a parent Activity

  4. 4

    calling parent activity method from fragment

  5. 5

    Calling fragment method from activity Android

  6. 6

    App Crashing when calling a Fragment from an Activity

  7. 7

    Calling a function when an activity is returned to from fragment

  8. 8

    Calling Activity from Fragment

  9. 9

    Calling fragment from activity

  10. 10

    Calling Fragment method from Activity,findFragmentById returns null

  11. 11

    Calling Fragment's method from Activity doesn't work?

  12. 12

    Calling Activity method inside Fragment that is not attached to Activity

  13. 13

    NullPointer exception while passing a value from activity to Interface method and retrieve in fragment android

  14. 14

    Calling a custom fragment from an activity

  15. 15

    calling an activity from fragment activity through Intent

  16. 16

    calling fragment method in Activity not working kotlin

  17. 17

    Call an activity method from a fragment

  18. 18

    Fragment method not accessible from Activity

  19. 19

    Call Fragment method from Activity

  20. 20

    Calling a fragment method from an Adapter

  21. 21

    Calling method from Fragment in ViewPager

  22. 22

    Calling a Fragment method from a singleton

  23. 23

    Call method in fragment from another fragment/activity

  24. 24

    Calling Activity method from FirebaseMessagingService

  25. 25

    Calling a method from Activity in Adapter

  26. 26

    Calling a method from an exported activity

  27. 27

    Calling method of activity from asynctask

  28. 28

    Navigate back to calling Fragment from another activity

  29. 29

    Calling Fragment from an activity and updating layout

HotTag

Archive