Fragment常见的两种重建方式,一种是经过调用setRetainInstance
来通知系统在重建Activity(例如屏幕配置改变)时保留此Fragment;另外一种方式是系统在重建Activity时自动重建Fragment,典型例子是FragmentActivity对管理的Fragment的重建。android
直接参考官方文档的解释:bash
Control whether a fragment instance is retained across Activity re-creation (such as from a configuration change). This can only be used with fragments not in the back stack. If set, the fragment lifecycle will be slightly different when an activity is recreated:app
调用了此方法后,Activity被销毁时,此Fragment会被保留(进程不消亡的前提下),Activity重建时,Fragment直接挂载。ide
原理:当配置发生变化时,Activity进入销毁过程,FragmentManager先销毁队列中Fragment的视图,而后检查每一个Fragment的retainInstance属性。若是retainInstance为false,FragmentManager会销毁该Fragment实例;若是retainInstance为true,则不会销毁该Fragment实例,Activity重建后,新的FragmentManager会找到保留的Fragment并为其建立视图。spa
FragmentActivity在配置改变被销毁时,FragmentManager中的Fragment状态会被保存下来,等以后Activity重建时,被销毁的Fragment也会被重建。因此在这种状况下,Activity重建时,不须要再在onCreate中建立新的Fragment,而是使用被自动重建的Fragment(能够经过tag找到)。Fragment的状态保存及重建过程能够在FragmentActivity的代码中查看。rest
当配置改变,Activity即将销毁时,FragmentActivity会先保存全部队列中的Fragment状态。code
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
markFragmentsCreated();
Parcelable p = mFragments.saveAllState();
if (p != null) {
outState.putParcelable(FRAGMENTS_TAG, p);
}
复制代码
mFragments为FragmentManager的引用,FragmentManager.saveAllState
返回一个包含须要保存的Fragment的Parcelable,此数据以后会用于重建这些Fragment。队列
查看FragmentManager.saveAllState
方法的实现,能够看出返回的Parcelable实际为一个FragmentManagerState实例,该类的数据成员定义为:进程
final class FragmentManagerState implements Parcelable {
FragmentState[] mActive;
int[] mAdded;
BackStackState[] mBackStack;
int mPrimaryNavActiveIndex = -1;
int mNextFragmentIndex;
}
复制代码
FragmentState的数据成员:文档
final class FragmentState implements Parcelable {
final String mClassName;
final int mIndex;
final boolean mFromLayout;
final int mFragmentId;
final int mContainerId;
final String mTag;
final boolean mRetainInstance;
final boolean mDetached;
final Bundle mArguments;
final boolean mHidden;
Bundle mSavedFragmentState;
Fragment mInstance;
}
复制代码
FragmentState包含描述Fragment的各个数据变量,足够从零从新建立一个被销毁的Fragment。
在保存了Fragment数据以后,Activity实例以及没有调用setRetainInstance(true)
的Fragment实例都被销毁。
而当Activity重建时,被销毁的Fragment也会被重建:
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
mFragments.attachHost(null /*parent*/);
super.onCreate(savedInstanceState);
NonConfigurationInstances nc =
(NonConfigurationInstances) getLastNonConfigurationInstance();
if (nc != null) {
mViewModelStore = nc.viewModelStore;
}
if (savedInstanceState != null) {
Parcelable p = savedInstanceState.getParcelable(FRAGMENTS_TAG);
mFragments.restoreAllState(p, nc != null ? nc.fragments : null);
复制代码
FragmentActivity经过调用FragmentManager的restoreAllState方法,重建以前保存下来并被销毁的Fragment。