调用setRetainInstance(true)的Fragment如何判断是否需要被保留?
setRetainInstance 保留机制的判断逻辑
1. 区分Activity临时销毁/永久销毁的核心依据
Android系统内部有专门的标记位区分两种销毁场景:
- 配置变更触发的临时销毁(屏幕旋转、语言切换、字体大小调整等场景):Activity内部的
mChangingConfigurations标记会被置为true,可通过isChangingConfigurations()方法查询该状态,此时系统明确销毁后会立刻重建新的Activity实例承接新配置。 - 永久销毁(用户按返回键、调用
finish()关闭Activity、系统低内存查杀进程等场景):上述标记位为false,销毁后不会再重建对应Activity实例。
2. Fragment判断是否保留实例的逻辑
只有同时满足以下两个条件,设置了setRetainInstance(true)的Fragment才会被保留:
- 开发者主动调用
setRetainInstance(true),默认值为false,不会触发保留逻辑 - 宿主Activity的
isChangingConfigurations()返回true,属于配置变更导致的临时销毁场景
具体执行流程如下:
- 宿主Activity触发销毁流程时,FragmentManager会遍历所有已添加的Fragment实例
- 对每个Fragment先校验
mRetainInstance标记是否为true,再校验宿主是否处于配置变更的临时销毁状态 - 两个条件都满足时,Fragment实例会从旧Activity的FragmentManager中剥离,存入
FragmentManagerNonConfig系统缓存结构,不会走完整销毁生命周期(仅执行onDetach()和旧Activity解绑,不会触发onDestroy()) - 新Activity实例重建完成后,新的FragmentManager会从缓存中取出保留的Fragment实例,重新绑定到新Activity上继续执行生命周期
- 任意条件不满足时,Fragment会走完整销毁流程,实例不会被保留,后续重建会生成全新的Fragment实例
注意:该机制仅保留Fragment实例本身,不会自动保留内部View树,View相关状态仍需要通过
onSaveInstanceState等方式自行保存恢复。另外AndroidX中setRetainInstance已被标记为废弃,官方更推荐使用ViewModel实现配置变更下的状态保留,逻辑更清晰也更安全。
内容的提问来源于stack exchange,提问作者Gissipi_453
相关产品推荐
相关产品推荐

