Prevent Fragment recovery in Android

2019-01-16 19:12发布

We are using Fragments and we don't need them to be automatically recovered when the Activity is recreated. But Android every time when Activity::onCreate(Bundle savedInstanceState) -> super.onCreate(savedInstanceState) is called, restores Fragments even if we use setRetainInstance(false) for those Fragments.

Moreover, in those Fragments Fragment.performCreateView() is called directly without going through Fragment::onAttach() and so on. Plus, some of the fields are null inside restored Fragment...

Does anybody know how to prevent Android from restoring fragments?

P.S. We know that in case of recreating Activity for config changes it could be done by adding to manifest android:configChanges="orientation|screenSize|screenLayout. But what about recreating activity in case of automatic memory cleaning?

6条回答
Deceive 欺骗
2楼-- · 2019-01-16 19:24

I also had a ViewPager so I checked the fragmentMananger if it had fragments in it and removed them in onCreate().

Using for example this thread: Remove all fragments from container.

FragmentManager fm = getSupportFragmentManager();
for (Fragment fragment: fm.getFragments()) {
  fm.beginTransaction().remove(fragment).commitNow();
}

commitNow() to remove fragments synchronosly.

查看更多
SAY GOODBYE
3楼-- · 2019-01-16 19:32

I removed the fragments in Activity's onCreate.

查看更多
We Are One
4楼-- · 2019-01-16 19:34

Those who got NPE with ViewPager when use this method described in the accepted answer, please override

ViewPager.onRestoreInstanceState(Parcelable state)

method and call

super.onRestoreInstanceState(null);

instead.

查看更多
放荡不羁爱自由
5楼-- · 2019-01-16 19:35

We finished by adding to activity:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(null);
}

It suppresses any saved data on create/recreate cycle of an Activity and avoids fragments auto re-creation.

查看更多
迷人小祖宗
6楼-- · 2019-01-16 19:42

View hierarchy in not restored automatically. So, in Fragment.onCreateView() or Activity.onCreate(), you have to restore all views (from xml or programmatically). Each ViewGroup that contains a fragment, must have the same ID as when you created it the first time. Once the view hierarchy is created, Android restores all fragments and put theirs views in the right ViewGroup thanks to the ID. Let say that Android remembers the ID of the ViewGroup on which a fragment was. This happens somewhere between onCreateView() and onStart().

查看更多
7楼-- · 2019-01-16 19:49

@goRGon 's answer was very useful for me, but such use cause serious problems when there is some more information you needs to forward to your activity after recreate.

Here is improved version that only removes "fragments", but keep every other parameters.

ID that is removed from bundle is part of android.support.v4.app.FragmentActivity class as FRAGMENTS_TAG field. It may of course change over time, but it's not expected.

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(createBundleNoFragmentRestore(savedInstanceState));
}

/**
 * Improve bundle to prevent restoring of fragments.
 * @param bundle bundle container
 * @return improved bundle with removed "fragments parcelable"
 */
private static Bundle createBundleNoFragmentRestore(Bundle bundle) {
    if (bundle != null) {
        bundle.remove("android:support:fragments");
    }
    return bundle;
}
查看更多
登录 后发表回答