我知道第一次使用该片段时应创建Fragment
并使用FragmentTransaction
将其添加到管理器中。但是稍后在配置更改(例如屏幕旋转)后,可以通过findFragmentById
或findFragmentbyTag
找到它。
但是在屏幕旋转时,我发现片段onAttach
,onCreate
,onCreateView
,onStart
,onResume
的构造函数和所有回调方法都被再次调用,即使片段是从未显式调用构造函数。
调用构造函数的事实意味着可以对碎片对象进行垃圾回收。那么,片段的哪一部分实际上存储在配置更改中?如果片段对象是垃圾回收并重新创建的,那么重新实现它的目的是什么?
最佳答案
该片段不被回收。如果在屏幕定向后登录了Fragment.toString()
,则将获得一个不同的值,这意味着这些片段实例是不同的,它们是从头开始创建的。所有生命周期方法都称为BUT,但您可以通过onSaveInstanceState(Bundle)
保留某些值。
对于您调用setRetainInstance(true)
的片段,情况并非如此。现在,唯一重复的生命周期方法是onCreateView
,onViewCreated
,(长时间停顿),onDestroyView
。实例相同,保留字段变量。
编辑:
在托管活动上调用onCreate之前,Android OS是否会自动销毁并创建片段并设置相同的标签和ID?
TL; DR:是的。FragmentState
类字段变量包含有关始终保留的一个片段的信息(以及其他标记和ID)。
旋转屏幕时,将调用FragmentManagerImpl.restoreAllState(...)
屏幕,该屏幕将获取保留的片段或实例化新的片段并将它们重新附加到新活动。这是Activity.onCreate(Bundle)
的一部分。
那么,片段的哪一部分实际上存储在配置更改中?
如上所述的FragmentState
加上您或框架在onSaveInstanceState(Bundle)
中编写的所有内容。如果片段标记为保留,则保存除视图层次结构以外的所有内容。
如果片段对象是垃圾回收并重新创建的,那么重新实现它的目的是什么?
如果它是从头开始销毁和创建的(新实例),则根本无法回收。您可以保留片段实例-同一实例在屏幕方向变化后仍可生存-或保存并恢复实例状态-旧片段实例被销毁,新片段实例被创建并用旧实例中的一些数据填充。