jumper0k
jumper0k

Reputation: 2166

android viewpager adapter and NullPointerException

Sometimes I'm getting NullPointerExceptions in google play reports, where (as I think) I use viewpager or it's adapter. This is my code:

private PagerAdapter mPagerAdapter;
private ViewPager mPagerView;

private static class PagerAdapter extends FragmentStatePagerAdapter {
    HashMap<Integer, PageFragment> mPageReferenceMap;

    public PagerAdapter(FragmentManager fm) {
        super(fm);
        mPageReferenceMap = new HashMap<Integer, PageFragment>();
    }

    @Override
    public int getCount() {
        return NUM_ITEMS;
    }

    @Override
    public Fragment getItem(int position) {
        PageFragment fragment = PageFragment.newInstance(position);
        mPageReferenceMap.put(position, fragment);
        return fragment;
    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        super.destroyItem(container, position, object);
        mPageReferenceMap.remove(position);
    }

    public PageFragment getFragment(int key) {
        return mPageReferenceMap.get(key);
    }

    @Override
    public int getItemPosition(Object object) {
        return POSITION_NONE;
    }
}

in onCreate():

    mPagerAdapter = new PagerAdapter(getSupportFragmentManager());
    mPagerView = (ViewPager) findViewById(R.id.pager);

Then, at this line I'm getting crash reports from some users:

 mPagerAdapter.getFragment(mPagerView.getCurrentItem()).whatEverFunctionFromFragment();

I call fragments this way in different places (independent of each other) - in onDismiss function of the dialog, in onItemClick of ListPopupWindow, etc - with different functions in fragment.

More info: I've got this error after I have done everything that sad Heinrisch. This error appears when user resumes to the activity. But I still don't understand how to fix it and why is it happening? Should I save mPageReferenceMap in onSaveInstanceState()? or in onStop()? What am I missing in lifecycle of Activity and Fragments?

Upvotes: 1

Views: 1889

Answers (2)

jumper0k
jumper0k

Reputation: 2166

The solution is storing mPageReferenceMap when app stops and restarts. The best way I've found for storing fragment references is putFragment() and getFragment() methods of FragmentManager.

Here is my code:

@Override
protected void onSaveInstanceState(Bundle savedInstanceState) {
    super.onSaveInstanceState(savedInstanceState);
    FragmentManager fm = getSupportFragmentManager();
    for(int i=0;i<mPagerAdapter.getCount();i++)
        fm.putFragment(savedInstanceState,"fragment"+Integer.toString(i),mPagerAdapter.getFragment(i));
}

and in onCreate() method (when Activity restarts):

    mPagerAdapter = new PagerAdapter(getSupportFragmentManager());
    if (savedInstanceState != null){
        FragmentManager fm = getSupportFragmentManager();
        for(int i=0;i<mPagerAdapter.getCount();i++){
            PageFragment pf = (PageFragment)fm.getFragment(savedInstanceState,"fragment"+Integer.toString(i));
            if(pf!=null)
                mPagerAdapter.putFragment(i,pf);
        }
    }

Upvotes: 0

Heinrisch
Heinrisch

Reputation: 5935

You should post the stacktrace that you are getting when reproducing this error.

Just guessing but might it be the mPageReferenceMap that returns null when resuming. The reason for this would be that the FragmentStatePagerAdapter is holding on to the fragments and is only calling getItem when it needs a new fragment. However, the FragmentStatePagerAdapter does not hold on to the information in mPageReferenceMap. So if the adapter restores the fragments without calling getItem, your fragments will be there but there will not be a reference in mPageReferenceMap.

Upvotes: 1

Related Questions