Android应用程序在使用Fragments和ViewPager一段时间后崩溃

当我尝试恢复我的碎片时,我的android应用崩溃了。 我没有添加任何自定义variables到我试图还原的捆绑包,这都是默认的。 我正在使用Fragments和ViewPager。 看我下面的代码片段

public static class MyAdapter extends FragmentStatePagerAdapter { public MyAdapter(FragmentManager fm) { super(fm); } @Override public int getCount() { return NUM_ITEMS; } public int getCurrentItemPosition(Fragment fragment){ return getItemPosition(fragment); } @Override public Fragment getItem(int position) { return ContentFragment.newInstance(position); } } public class MyActivity extends FragmentActivity { static final int NUM_ITEMS = 100000; public int currentSelectedPage; private int changeToFragmentIndex; public DateTime midDate; MyAdapter mAdapter; ViewPager mPager; /** Called when the activity is first created. */ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.diary); MyApplication application = (MyApplication)getApplication(); application.dataController.myActivity = this; mAdapter = new MyAdapter(getSupportFragmentManager()); mPager = (ViewPager)findViewById(R.id.pager); mPager.setAdapter(mAdapter); int newDay = application.daysBetween(DateTime.now(), DateTime.parse(application.day.dateToShortString())); this.currentSelectedPage = NUM_ITEMS/2+newDay; mPager.setCurrentItem(NUM_ITEMS/2+newDay); mPager.setOnPageChangeListener(new SimpleOnPageChangeListener(){ public void onPageSelected(int position){ currentSelectedPage = position; ContentFragment fragment = (ContentFragment) mAdapter.instantiateItem(mPager, currentSelectedPage); fragment.loadData(); } }); } } public class ContentFragment extends Fragment { private View v; static final int NUM_ITEMS = 100000; static ContentFragment newInstance(int num) { ContentFragment f = new ContentFragment(); return f; } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { if (container == null) return null; v = inflater.inflate(R.layout.diarycontent, container, false); return v; } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); } @Override public void onSaveInstanceState(Bundle savedInstanceState){ super.onSaveInstanceState(savedInstanceState); setUserVisibleHint(true); } } 

我收到这个stackstrace:

 Caused by: java.lang.NullPointerException at android.support.v4.app.FragmentManagerImpl.getFragment(FragmentManager.java:519) at android.support.v4.app.FragmentStatePagerAdapter.restoreState(FragmentStatePagerAdapter.java:1 55) at android.support.v4.view.ViewPager.onRestoreInstanceState(ViewPager.java:522) 

据我所知这可能是一个已知的问题与支持包,并且一个可能的解决scheme将是在onSaveInstanceState中使用setUserVisibleHint(true)。 但是这并没有帮助。

有谁知道这个问题的另一个解决scheme,或者我做错了什么?

Solutions Collecting From Web of "Android应用程序在使用Fragments和ViewPager一段时间后崩溃"

一旦我开始在Tab中使用带有FragmentStatePagerAdapter的ViewPager,我遇到了同样types的问题。

然后我和这个问题的所有论坛都玩过,打破了我的头两天,看看为什么会出现这个问题,怎么解决,但是没有find符合我的要求的完美解决scheme。

我得到的解决scheme,以避免NPE崩溃使用FragmentPagerAdapter而不是FragmentStatePagerAdapter。 当我replaceFragmentPagerAdapter,而不是FragmentStatePagerAdapter,那么不会遇到NPE崩溃问题,但同一页面没有刷新自己的进一步导航(这是我的要求)。

最后覆盖FragmentStatePagerAdapter上的saveState方法,一切工作正常。

 @Override public Parcelable saveState() { // Do Nothing return null; } 

我如何轻松地重现此问题:
我正在使用更高版本(4.1)的设备,并遵循以下步骤:
1.转到设置 – >开发人员选项。
2.单击选项“不要保留活动”。

现在我玩我的应用程序。

每当应用程序由于android.support.v4.app.FragmentManagerImpl.getFragment(Unknown Source)处的NPE而崩溃时,覆盖saveState()方法。 但是覆盖saveState()之后,没有注册崩溃。

我希望这样做你不会有任何问题。

我最初使用@Lalit Kumar Sahoobuild议的解决scheme。 但是,我注意到一个严重的问题:每次旋转设备时, 碎片pipe理器都会添加新的碎片而不删除旧碎片 。 所以我进一步search,我find了一个解决schemebuild议( 后#1 )的错误报告。 我使用了这个修复程序,并用我的应用程序进行了testing,问题似乎已经解决,没有任何副作用:

解决方法:在项目的src / android / support / v4 / app文件夹中创build自定义的FragmentStatePagerAdapter并使用它。

 package android.support.v4.app; import android.os.Bundle; import android.view.ViewGroup; public abstract class FixedFragmentStatePagerAdapter extends FragmentStatePagerAdapter { public FixedFragmentStatePagerAdapter(FragmentManager fm) { super(fm); } @Override public Object instantiateItem(ViewGroup container, int position) { Fragment f = (Fragment)super.instantiateItem(container, position); Bundle savedFragmentState = f.mSavedFragmentState; if (savedFragmentState != null) { savedFragmentState.setClassLoader(f.getClass().getClassLoader()); } return f; } } 

你为什么这样做:

 mPager.setOnPageChangeListener(new SimpleOnPageChangeListener(){ public void onPageSelected(int position){ currentSelectedPage = position; ContentFragment fragment = (ContentFragment) mAdapter.instantiateItem(mPager, currentSelectedPage); fragment.loadData(); } }); 

这个:

 @Override public Fragment getItem(int position) { return ContentFragment.newInstance(position); } 

实例化片段。

你可以像这样在片段中加载数据:

 @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); loadData(); }