Android中FragmentManager进行片段回收的目的是啥?
Posted
技术标签:
【中文标题】Android中FragmentManager进行片段回收的目的是啥?【英文标题】:What is the purpose of fragment recycling by FragmentManager in Android?Android中FragmentManager进行片段回收的目的是什么? 【发布时间】:2015-04-11 09:26:59 【问题描述】:我知道第一次使用片段时应该使用FragmentTransaction
创建Fragment
并将其添加到管理器中。但后来在屏幕旋转等配置更改后,可以通过findFragmentById
或findFragmentbyTag
找到。
但是在屏幕旋转时,我发现片段onAttach
、onCreate
、onCreateView
、onStart
、onResume
的构造函数和所有回调方法都被再次调用了,即使片段是从findFragmentByTag
返回,没有显式调用构造函数。
构造函数被调用的事实意味着片段对象可以被垃圾收集。那么片段的哪一部分实际上存储在配置更改上?如果fragment对象被垃圾回收并重新创建,那么回收它的目的是什么?
【问题讨论】:
【参考方案1】:片段没有被回收。如果您在屏幕定向后登录Fragment.toString()
,您将获得不同的值,这意味着这些片段实例是不同的,是从头开始创建的。所有生命周期方法都称为但是您可以通过onSaveInstanceState(Bundle)
保留一些值。
这不适用于您调用setRetainInstance(true)
的片段。现在唯一重复的生命周期方法是onCreateView
、onViewCreated
、(长时间停顿)、onDestroyView
。实例相同,保留字段变量。
编辑:
android OS 是否会在宿主 Activity 上调用 onCreate 之前自动销毁和创建 Fragment 并设置相同的 Tag 和 ID?
TL;DR:是的。
FragmentState
类字段变量包含有关一个片段的信息,该片段始终保留(以及其他标签和 ID)。
当你旋转屏幕时,FragmentManagerImpl.restoreAllState(...)
被调用,它要么抓取保留的片段,要么实例化新的片段并将它们重新附加到新的活动。这是Activity.onCreate(Bundle)
的一部分。
那么片段的哪一部分实际存储在配置更改上?
如上所述的FragmentState
加上您或框架在onSaveInstanceState(Bundle)
中写入的任何内容。如果片段被标记为保留,则保存视图层次结构以外的所有内容。
如果fragment对象被垃圾回收并重新创建,那么回收它的目的是什么?
如果它被销毁并从头开始创建(新实例),它根本不会被回收。您可以保留片段实例 - 相同的实例在屏幕方向更改后仍然存在 - 或保存并恢复实例状态 - 旧片段实例被销毁,新片段实例被创建并填充来自旧实例的一些数据。
【讨论】:
那么,如何在宿主Activity的onCreate
中调用findFragmentByTag
来获取片段的引用呢? Android OS 是否会在旋转后在宿主 Activity 上调用 onCreate
之前自动销毁并创建 Fragment 并设置相同的 Tag 和 ID?
@jenddy 嗨,请检查更新的答案。简而言之:是的,Activity 能够记住标签和 ID。以上是关于Android中FragmentManager进行片段回收的目的是啥?的主要内容,如果未能解决你的问题,请参考以下文章
android.support.v4.app.FragmentManager 还是 android.app.FragmentManager?
无法从 android.app.FragmentManager 转换为 android.support.v4.app.FragmentManager
Android 11(仅限)FragmentManager 崩溃 - FragmentManager 已被销毁