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

Android应用程序在使用Fragments和ViewPager一段时间后崩溃,android,crash,fragment,android-viewpager,Android,Crash,Fragment,Android Viewpager,我的android应用程序在试图恢复我的碎片时出现崩溃问题。我没有向试图恢复的包中添加任何自定义变量,这都是默认值。我正在使用片段和ViewPager。请参见下面的我的代码片段: public static class MyAdapter extends FragmentStatePagerAdapter { public MyAdapter(FragmentManager fm) { super(fm); } @Override public

我的android应用程序在试图恢复我的碎片时出现崩溃问题。我没有向试图恢复的包中添加任何自定义变量,这都是默认值。我正在使用片段和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);
}
}
我收到这封信:

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)
据我所知,这可能是支持包的一个已知问题,一个可能的解决方案是在onSaveInstanceState中使用setUserVisibleHint(true)。但那没用


有人知道问题的另一种解决方案吗?或者我做错了什么?

你到底为什么要这样做:

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

当我开始使用带有FragmentStatePagerAdapter的ViewPager时,我也遇到过同样的问题

然后,我与所有与此问题相关的论坛一起玩了两天,打破了我的头脑,以了解为什么会发生此问题以及如何解决它,但没有找到任何符合我要求的完美解决方案

我得到了解决方案,因为为了避免NPE崩溃,使用FragmentPagerAdapter而不是FragmentStatePagerAdapter。当我更换FragmentPagerAdapter而不是FragmentStatePagerAdapter时,就不会面临NPE崩溃问题,但同一页面不会刷新以进行进一步导航(这是我的要求)

最后,在FragmentStatePagerAdapter上重写saveState方法,一切正常

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

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

现在我玩我的应用程序

每次应用程序由于android.support.v4.app.FragmentManagerImpl.getFragment(未知源)上的NPE而崩溃时重写saveState()方法之前。但是在覆盖saveState()之后,不会注册崩溃


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

我最初使用@Lalit Kumar Sahoo建议的解决方案。但是,我注意到一个严重的问题:每次我旋转设备时,片段管理器都会添加新片段,而不会删除旧片段。所以我进一步搜索,发现了一个带有解决建议的bug报告()。我使用了此修复程序并用我的应用程序进行了测试,问题似乎得到了解决,没有任何副作用:

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


我这样做是因为我在正确更新片段时遇到了一些麻烦。我测试了你的代码,崩溃仍然发生。这为我解决了它,或者隐藏了它。嗨@xteci,你解决了这个问题吗?我也遇到过这样的错误,但仍然找不到解决方案。我也是,你们找到什么了吗@hakimYou可以使用这个答案它对我有效这个解决方案会完全破坏视图状态&每个片段都会再次实例化,而不会进行任何视图状态恢复。仅当不希望恢复viewstate时才有用。并非对所有情况都有用
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;
  }
}