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并将其添加到管理器中。但后来在屏幕旋转等配置更改后,可以通过findFragmentByIdfindFragmentbyTag找到。

但是在屏幕旋转时,我发现片段onAttachonCreateonCreateViewonStartonResume的构造函数和所有回调方法都被再次调用了,即使片段是从findFragmentByTag 返回,没有显式调用构造函数。

构造函数被调用的事实意味着片段对象可以被垃圾收集。那么片段的哪一部分实际上存储在配置更改上?如果fragment对象被垃圾回收并重新创建,那么回收它的目的是什么?

【问题讨论】:

【参考方案1】:

片段没有被回收。如果您在屏幕定向后登录Fragment.toString(),您将获得不同的值,这意味着这些片段实例是不同的,是从头开始创建的。所有生命周期方法都称为但是您可以通过onSaveInstanceState(Bundle) 保留一些值。

这不适用于您调用setRetainInstance(true) 的片段。现在唯一重复的生命周期方法是onCreateViewonViewCreated、(长时间停顿)、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 已被销毁

在 FragmentManager 中更改片段

Android:FragmentManager 无法替换 FrameLayout 的问题

片段声明的目标片段不属于此 FragmentManager - Android