美文网首页
app崩溃后,带fragment的activity恢复的坑

app崩溃后,带fragment的activity恢复的坑

作者: 石野小真人 | 来源:发表于2018-04-09 10:27 被阅读819次

    遇到的场景

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

    https://blog.csdn.net/c10wtiybq1ye3/article/details/78098520
    https://juejin.im/post/5a2e4c825188257df846206c

    解决办法:

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

    @Override
        protected void onSaveInstanceState(Bundle outState) {
            //super.onSaveInstanceState(outState);
        }
    

    但这还会存在一个问题:
    一些恢复时必须的字段无法保存,比如开启这个activity的intent传入的用于初始化的字段.
    而实际测试过程中,activity正常恢复了,很奇怪...什么原因呢?

    参考:
    关于Activity被回收,Fragment还在的问题

    相关文章

      网友评论

          本文标题:app崩溃后,带fragment的activity恢复的坑

          本文链接:https://www.haomeiwen.com/subject/xopbhftx.html