1

有时我在谷歌播放报告中得到 NullPointerExceptions,其中(我认为)我使用 viewpager 或它的适配器。这是我的代码:

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;
    }
}

在 onCreate() 中:

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

然后,在这一行,我收到了一些用户的崩溃报告:

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

我在不同的地方(彼此独立)以这种方式调用片段 - 在对话框的 onDismiss 函数中,在 ListPopupWindow 的 onItemClick 等中 - 在片段中具有不同的功能。

更多信息:在完成所有让Heinrisch伤心的事情后,我遇到了这个错误。当用户恢复活动时会出现此错误。但我仍然不明白如何解决它,为什么会这样?我应该保存mPageReferenceMap在 onSaveInstanceState() 中吗?还是在 onStop() 中?我在 Activity 和 Fragments 的生命周期中缺少什么?

4

2 回答 2

1

您应该发布在重现此错误时获得的堆栈跟踪。

只是猜测,但可能是恢复时返回 null 的 mPageReferenceMap。这样做的原因是 FragmentStatePagerAdapter 持有片段,并且仅在需要新片段时才调用 getItem。但是,FragmentStatePagerAdapter 不保留 mPageReferenceMap 中的信息。因此,如果适配器在不调用 getItem 的情况下恢复片段,您的片段将在那里,但在 mPageReferenceMap 中不会有引用。

于 2012-12-20T13:00:08.550 回答
0

mPageReferenceMap解决方案是在应用停止和重新启动时进行存储。我发现存储片段引用的最佳方法是FragmentManager 的putFragment()getFragment()方法。

这是我的代码:

@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));
}

并在 onCreate() 方法中(当 Activity 重新启动时):

    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);
        }
    }
于 2012-12-25T13:33:40.287 回答