栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Android 使用ViewTreeLifecycleOwner获取Lifecycle

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Android 使用ViewTreeLifecycleOwner获取Lifecycle

转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/125585064
本文出自【赵彦军的博客】

文章目录
  • ViewTreeLifecycleOwner是什么?
  • 实现原理?
    • ComponentActivity
    • Fragment
    • DialogFragment
    • ComponentDialog
  • Fragment 作为 LifecycleOwner 遇到的坑
    • onCreate
    • onViewCreated
    • getViewLifecycleOwnerLiveData
    • lifecycleScope
  • 总结

ViewTreeLifecycleOwner是什么?

ViewTreeLifecycleOwner 是Lifecycle KTX中提供的View的一个扩展方法,可以快速地获取一个最近的Fragment或者Activity的LifecycleOwner。

view.findViewTreeLifecycleOwner()

实现原理? ComponentActivity

通过 ViewTreeLifecycleOwner.set 将当前 lifecycle 设置到decorView

Fragment

通过 ViewTreeLifecycleOwner.set 将当前 lifecycle 设置到根view

DialogFragment

通过 ViewTreeLifecycleOwner.set 将当前 lifecycle 设置到decorView

ComponentDialog

通过 ViewTreeLifecycleOwner.set 将当前 lifecycle 设置到decorView

Fragment 作为 LifecycleOwner 遇到的坑 onCreate

在 Fragment 的 onCreate 用 this 做 LifecycleOwner 没有问题。

class MyFragment : Fragment() {

    private val viewModel by activityViewModels()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        
        viewModel.some.observe(this) { }
    }
}

因为在 Fragment Destory 会自动移除监听。

onViewCreated

那么我们在 onViewCreated 还能使用上面的监听代码吗?

试试看

class MyFragment : Fragment() {

    private val viewModel by activityViewModels()

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        viewModel.some.observe(this) {
            Log.d("yu--", "some $it")
        }
    }
}

这就行了? 等等,会报错

意思是,这里的 LifecyclerOwner 要使用 viewLifecyclerOwner , 代码如下:
为什么会报错?

LiveData 之所以能够防止泄露,是当 LifecycleOwner 生命周期走到 DESTROYED 的时候会 remove 调其关联的 Observer。


是由于 Fragment 的 Lifecycle 与 Fragment#mView 的 Lifecycle 不一致导致我们订阅 LiveData 的时机和所使用的 LivecycleOwner 不匹配

明白了问题原因,解决思路也就清楚了:必须要保证订阅的时机和所使用的 LifecycleOwner相匹配,即要么调整订阅时机,要么修改LifecycleOwner。

getViewLifecycleOwnerLiveData

顺道提一下,与 getViewLifecycleOwner 同时新增的还有 getViewLifecycleOwnerLiveData。从前面贴的源码中对 mViewLifecycleOwnerLiveData 的使用,应该可以猜出它的作用:它是前文讨论的思路1的实现方案,即使在 onCreate 中订阅,由于在 onCreateView 中对 LiveData 进行了重新设置,所以重建后的 View 也可以更新数据。

// Then inform any Observers of the new LifecycleOwner
mViewLifecycleOwnerLiveData.setValue(mViewLifecycleOwner);

需要特别注意的是,根据 MVVM 最佳实践,我们希望由 ViewModel 而不是 Fragment 持有 LiveData,所以不再推荐使用 getViewLifecycleOwnerLiveData。

lifecycleScope

前面都是以 LiveData 为例介绍对 ViewLifecycleOwner 的使用, 如今大家也越来越多的开始使用协程的 StateFlow , 同样要注意不要错用 LifecycleOwner。

订阅 StateFlow 需要 CoroutineScope, AndroidX 提供了基于 LifecycleOwner 的扩展方法。

val LifecycleOwner.lifecycleScope: LifecycleCoroutineScope
    get() = lifecycle.coroutineScope

当我们在 Fragment 中获取 lifecycleScope 时,切记要使用 ViewLifecycleOwner。

相关文章:Jetpack 易错分享:还在使用 Fragment 作为 LifecycleOwner ?

总结

随着 MVVM 的普及,我们可能需要在View 内部基于lifecycle 进行livedata 订阅等工作,当View嵌套比较深时,使用ViewTreeLifecycleOwner扩展方法可以避免lifecycle的层层传递,简化代码.

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1005764.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号