Fragment调用 setRetainInstance 的原理

转载自:http://blog.csdn.net/gaugamela/article https://blog.csdn.net/Gaugamela/article/details/56280384

Fragment 具有属性 retainInstance ,默认值为 false。
当设备旋转时,fragment 会随托管 activity 一起销毁并重建(重建的时候,是通过反射 fragment 的无参构造函数得到实例存到 FragmentManager 里面的)。

调用 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(true) 方法,
并且因设备配置改变,托管 Activity 正在被销毁的条件下,
fragment 才会短暂的处于保留状态。

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

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


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

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

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

猜你喜欢

转载自blog.csdn.net/OneDeveloper/article/details/82424080
今日推荐