LifecycleOwner: Fragment (self) 和 Fragment#viewLifecycle 的区别
LifecycleOwner: difference between Fragment (self) and Fragment#viewLifecycle
使用Android X
和Android Architecture Components
,即下面...
- 导航
- 生命周期
- 视图模型
...使 Android 开发更容易,应用程序更好更稳定。
当使用 ViewModel
为 Fragment
公开 LiveData
时,目前有两个 LifecycleOwners 可用于 观察:
Fragment
本身或
-
Fragment
的 属性 mViewLifecycleOwner
.
直到现在,我一直只使用 Fragment
本身来处理 ViewModel
暴露的所有 LiveData
。
因为我喜欢经常升级到最新的 alpha 和 beta 来生活在边缘,我最近升级到:
- 导航ktx版本
2.2.0-rc01
;
- activity ktx 版本
1.1.0-rc01
;
- 片段 ktx 版本
1.2.0-rc01
;
- 生命周期 ktx 版本
2.2.0-rc01
;
幸运的是,在这个日期(2019 年 11 月 1 日),所有候选版本都可用。
这导致在旧 java 代码中警告我:
怎么会有两个LifecycleOwners?
在设置 Fragment 的数据绑定布局的生命周期所有者(使用 Databinding
库)时,我是否也应该遵循此警告?
那么Fragment本身作为LifecycleOwener
有什么用呢?
有两种不同的生命周期,因为 Fragment 本身的生命周期比 Fragment 的视图长。
有许多事件会导致 Fragment 的视图被销毁,但目前 Fragment 本身仍保持活动状态:
- 将 Fragment 放入后栈(即,当您
navigate()
到另一个 Fragment 时)
- 在片段上调用
detach()
- 在片段上调用
setMaxLifecycle(Lifecycle.State.CREATED)
在这些情况下,Fragment 的视图被销毁,将 Fragment 视图的生命周期移至 DESTROYED
。然而,Fragment 本身的生命周期是 而不是 被破坏的——它通常保持 CREATED
。这意味着 Fragment 可以经历 onCreateView()
-> onViewCreated()
-> onDestroyView()
的多个循环,而只经历 onCreate()
一次。
当涉及到 LiveData
的工作方式时,这就会成为一个问题。当你 observe
一个 LiveData
时,LiveData
会在生命周期达到 DESTROYED
时自动注销观察者。但是如果你使用 Fragment 的生命周期到 onCreateView()
中的 observe
等,那么尽管视图被销毁,那个注册的观察者在 onDestroyView()
之后仍然存在。这意味着您的 Fragment 第二次通过 onCreateView()
,您实际上会创建第二个活动的观察者,同时 运行。然后下一次是三个观察者。
通过在 onCreateView()
/onViewCreated()
中使用视图 LifecycleOwner,您可以确保一次只有一个活动的观察者 运行 并且观察者与之前的视图实例相关联与视图一起被正确销毁。因此,是的,在 onCreateView()
或 onViewCreated()
中,包括使用数据绑定时,您应该始终使用 getViewLifecycleOwner()
作为 LifecycleOwner。
当然,如果您在 onCreate()
中注册观察者,那么 LifecycleOwner 视图还不存在(它是在 onCreateView()
之前创建的)并且您没有多个注册问题,这就是为什么 Lint 检查特别不适用于在 onCreate()
时间完成的任何注册。在那些情况下,使用 Fragment 的生命周期本身是绝对正确的。
根据 Fragments: Past, Present, and Future talk,Fragment 未来的一项改进是将两个生命周期结合在一起,每当 Fragment 的视图被销毁时总是销毁 Fragment。这在 Fragments 的任何已发布版本、alpha 版或其他版本中尚不可用。
使用Android X
和Android Architecture Components
,即下面...
- 导航
- 生命周期
- 视图模型
...使 Android 开发更容易,应用程序更好更稳定。
当使用 ViewModel
为 Fragment
公开 LiveData
时,目前有两个 LifecycleOwners 可用于 观察:
Fragment
本身或-
Fragment
的 属性mViewLifecycleOwner
.
直到现在,我一直只使用 Fragment
本身来处理 ViewModel
暴露的所有 LiveData
。
因为我喜欢经常升级到最新的 alpha 和 beta 来生活在边缘,我最近升级到:
- 导航ktx版本
2.2.0-rc01
; - activity ktx 版本
1.1.0-rc01
; - 片段 ktx 版本
1.2.0-rc01
; - 生命周期 ktx 版本
2.2.0-rc01
;
幸运的是,在这个日期(2019 年 11 月 1 日),所有候选版本都可用。
这导致在旧 java 代码中警告我:
怎么会有两个LifecycleOwners?
在设置 Fragment 的数据绑定布局的生命周期所有者(使用 Databinding
库)时,我是否也应该遵循此警告?
那么Fragment本身作为LifecycleOwener
有什么用呢?
有两种不同的生命周期,因为 Fragment 本身的生命周期比 Fragment 的视图长。
有许多事件会导致 Fragment 的视图被销毁,但目前 Fragment 本身仍保持活动状态:
- 将 Fragment 放入后栈(即,当您
navigate()
到另一个 Fragment 时) - 在片段上调用
detach()
- 在片段上调用
setMaxLifecycle(Lifecycle.State.CREATED)
在这些情况下,Fragment 的视图被销毁,将 Fragment 视图的生命周期移至 DESTROYED
。然而,Fragment 本身的生命周期是 而不是 被破坏的——它通常保持 CREATED
。这意味着 Fragment 可以经历 onCreateView()
-> onViewCreated()
-> onDestroyView()
的多个循环,而只经历 onCreate()
一次。
当涉及到 LiveData
的工作方式时,这就会成为一个问题。当你 observe
一个 LiveData
时,LiveData
会在生命周期达到 DESTROYED
时自动注销观察者。但是如果你使用 Fragment 的生命周期到 onCreateView()
中的 observe
等,那么尽管视图被销毁,那个注册的观察者在 onDestroyView()
之后仍然存在。这意味着您的 Fragment 第二次通过 onCreateView()
,您实际上会创建第二个活动的观察者,同时 运行。然后下一次是三个观察者。
通过在 onCreateView()
/onViewCreated()
中使用视图 LifecycleOwner,您可以确保一次只有一个活动的观察者 运行 并且观察者与之前的视图实例相关联与视图一起被正确销毁。因此,是的,在 onCreateView()
或 onViewCreated()
中,包括使用数据绑定时,您应该始终使用 getViewLifecycleOwner()
作为 LifecycleOwner。
当然,如果您在 onCreate()
中注册观察者,那么 LifecycleOwner 视图还不存在(它是在 onCreateView()
之前创建的)并且您没有多个注册问题,这就是为什么 Lint 检查特别不适用于在 onCreate()
时间完成的任何注册。在那些情况下,使用 Fragment 的生命周期本身是绝对正确的。
根据 Fragments: Past, Present, and Future talk,Fragment 未来的一项改进是将两个生命周期结合在一起,每当 Fragment 的视图被销毁时总是销毁 Fragment。这在 Fragments 的任何已发布版本、alpha 版或其他版本中尚不可用。