设备旋转时创建新Fragment与获取现有实例的差异及retainInstance疑问
关于Fragment retainInstance的核心疑问解答
我来帮你把这个Fragment实例保留的逻辑理清楚,其实这里的关键点在于Android配置变化时的Fragment恢复机制和retainInstance参数的实际作用是两个不同的东西:
为什么旋转时总能从FragmentManager拿到“现有”Fragment?
不管你把retainInstance设为true还是false,当设备发生旋转这类配置变化时,Android系统都会自动帮你做一件事:保存当前Activity中所有Fragment的状态信息(包括它们的tag、ID、视图状态等)。当Activity重建完成后,FragmentManager会自动根据这些保存的信息,把Fragment重新关联到新的Activity上:
- 如果
retainInstance=true:直接复用原来的Fragment实例,只是把它从旧Activity上解绑,再绑定到新Activity上。 - 如果
retainInstance=false:系统会先销毁原来的Fragment实例,然后根据保存的状态信息创建一个全新的Fragment实例,并恢复它的视图状态。
你代码里显示的"Reusing existing",应该是通过findFragmentByTag或findFragmentById判断实例不为null,但要注意:这个“现有”在retainInstance=false的情况下,其实是系统重建后的新实例,只是它的标识(tag/id)和之前一致,所以你的判断逻辑认为是“已存在”的。
为什么成员变量的保留情况不一样?
这才是retainInstance参数真正起作用的地方:
- 当
retainInstance=true:Fragment的实例本身不会被销毁,只会经历onDetach()→onAttach()的流程,所以你修改过的成员变量(比如test)会完整保留,旋转后自然能看到"test = yes!"。 - 当
retainInstance=false:原来的Fragment实例会被彻底销毁,新创建的实例会用默认值初始化成员变量——除非你手动把变量保存到onSaveInstanceState的Bundle里,再在重建时恢复。比如如果你的test变量没做状态保存,那新实例的test就是初始值"no!"。
如果想在retainInstance=false时也保留自定义成员变量,可以这样做:
@Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); // 保存test变量到状态Bundle outState.putString("test_key", test); } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 从保存的状态中恢复test变量 if (savedInstanceState != null) { test = savedInstanceState.getString("test_key", "no!"); } }
内容的提问来源于stack exchange,提问作者Damn Vegetables
相关产品推荐
相关产品推荐

