遇到的场景

activity内一个viewpager包含三个fragment,都是通过new fragment()后add到pageradater中:

pages = new ArrayList<>();

productPage = new CategoryItemDetailFragment();

pages.add(productPage);

detailPage = new ItemDetailPageFregment();

detailPage.setHostActivity(this);

pages.add(detailPage);

specPage = new ItemSpecFragment();

specPage.setHostActivity(this);

pages.add(specPage);

pagerAdapter = new FragAdapter(getSupportFragmentManager(),pages);

当app crash后,该activity试图恢复,界面都正常显示,但是点击某些按钮无反应,调试得知:

fragment.getActivity()为null

fragment中的所有view对象都为null

fragment中的成员变量很多为null.

原因:

app crash时,fragment状态自动保存

重新恢复时,自动恢复原原来的三个fragment,但同时,activity的oncreate方法也走了,上述的viewpager初始化代码运行,又new了三个fragment.而且,恢复的fragment刚好盖在new出来的fragment上面.点击界面按钮,事件被恢复的fragment捕获,代码运行在此对象中,所以看到的很多东西都为null.

可以看到FragmentActivity中保存fragment状态的代码:

protected void onSaveInstanceState(Bundle outState) {

super.onSaveInstanceState(outState);

Parcelable p = mFragments.saveAllState();

if (p != null) {

outState.putParcelable(FRAGMENTS_TAG, p);

}

if (mPendingFragmentActivityResults.size() > 0) {

outState.putInt(NEXT_CANDIDATE_REQUEST_INDEX_TAG, mNextCandidateRequestIndex);

int[] requestCodes = new int[mPendingFragmentActivityResults.size()];

String[] fragmentWhos = new String[mPendingFragmentActivityResults.size()];

for (int i = 0; i < mPendingFragmentActivityResults.size(); i++) {

requestCodes[i] = mPendingFragmentActivityResults.keyAt(i);

fragmentWhos[i] = mPendingFragmentActivityResults.valueAt(i);

}

outState.putIntArray(ALLOCATED_REQUEST_INDICIES_TAG, requestCodes);

outState.putStringArray(REQUEST_FRAGMENT_WHO_TAG, fragmentWhos);

}

}

解决办法:

复写宿主activity的onSaveInstanceState(Bundle outState),不调用super.onSaveInstanceState(outState)

@Override

protected void onSaveInstanceState(Bundle outState) {

//super.onSaveInstanceState(outState);

}

但这还会存在一个问题:

一些恢复时必须的字段无法保存,比如开启这个activity的intent传入的用于初始化的字段.

而实际测试过程中,activity正常恢复了,很奇怪...什么原因呢?

更多推荐