Fragment调用setRetainInstance的原理

Fragment具有属性retainInstance,默认值为false。
当设备旋转时,fragment会随托管activity一起销毁并重建。

调用setRetainInstance(true)方法可保留fragment,示例代码如下:

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

已保留的fragment不会随着activity一起被销毁;
相反,它会一直保留(进程不消亡的前提下),并在需要时原封不动地传递给新的Activity。


保留Fragment的原理是:
当设备配置发生变化时,FragmentManager首先销毁队列中fragment的视图(因为可能有更合适的匹配资源);
紧接着,FragmentManager将检查每个fragment的retainInstance属性值。

如果retainInstance属性值为false,FragmentManager会立即销毁该fragment实例。
随后,为适应新的设备配置,新的Activity的新的FragmentManager会创建一个新的fragment及其视图。

如果retainInstance属性值为true,则该fragment的视图立即被销毁,但fragment本身不会被销毁。
为适应新的设备配置,当新的Activity创建后,新的FragmentManager会找到被保留的fragment,并重新创建其试图。


虽然保留的fragment没有被销毁,但它已脱离消亡中的activity并处于保留状态。
尽管此时的fragment仍然存在,但已经没有任何activity托管它,其生命周期如下图所示:
Fragment调用setRetainInstance的原理_第1张图片


需要说明的是:
只有调用了fragment的setRetainInstance(true)方法,
并且因设备配置改变,托管Activity正在被销毁的条件下,
fragment才会短暂的处于保留状态。

如果activity是因操作系统需要回收内存而被销毁,则所有的fragment也会随之销毁。

相对而言,onSaveInstanceState可以更长久的保持数据。
当Activity所在进程被系统杀死(非用户主动关闭),系统重新创建activity时,
将恢复onSaveInstanceState中保留的数据。


从上文我们知道,当Fragment设置了setRetainInstance(true)后,
在设备旋转等情况下,该Fragment可以暂时与Activity分离。

如果此时Fragment持有的后台线程,例如AsyncTask中的后台操作等,
需要使用Fragment的Context等信息,就可能出现错误。

为此,Fragment中定义了isAdded接口,
用于判断Fragment是否已经绑定到某个Activity。

你可能感兴趣的:(Android开发)