Android 使用ViewTreeLifecycleOwner获取Lifecycle

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

ViewTreeLifecycleOwner是什么?

ViewTreeLifecycleOwnerLifecycle KTX中提供的View的一个扩展方法,可以快速地获取一个最近的Fragment或者ActivityLifecycleOwner

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

FragmentonCreatethisLifecycleOwner 没有问题。

class MyFragment : Fragment() {

    private val viewModel by activityViewModels<MyViewModel>()

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

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

onViewCreated

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

试试看

class MyFragment : Fragment() {

    private val viewModel by activityViewModels<MyViewModel>()

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

这就行了? 等等,会报错
在这里插入图片描述
意思是,这里的 LifecyclerOwner 要使用 viewLifecyclerOwner , 代码如下:ai
为什么会报错?

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

在这里插入图片描述
是由于 FragmentLifecycleFragment#mViewLifecycle 不一致导致我们订阅 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 需要 CoroutineScopeAndroidX 提供了基于 LifecycleOwner 的扩展方法。

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

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

在这里插入图片描述

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

总结

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

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android开发中,生命周期是指一个组件(如Activity、Fragment、Service等)在、运行和销毁过程中所经历的状态变化。通过监听组件的生命周期,我们可以在适当的时候执行一些操作,比如在Activity的onResume方法中启动一些服务或者在Activity的onPause方法中保存数据。 在Android Jetpack中,引入了Lifecycle库来帮助开发者更方便地管理和监听组件的生命周期。通过实现LifecycleObserver接口,我们可以定义一个观察者类,然后在这个类中使用@OnLifecycleEvent注解来标识需要在特定生命周期事件发生时执行的方法。 例如,我们可以定义一个MyLifeCycleServiceObserver类,实现LifecycleObserver接口,并在其中使用@OnLifecycleEvent注解来标识在Service的生命周期中需要执行的方法。在这些方法中,我们可以进行一些业务逻辑的处理,比如在Service的onCreate方法中进行初始化操作,在onDestroy方法中进行资源释放。 在AndroidX库中,默认的Activity已经实现了LifecycleOwner接口,因此我们可以直接在Activity中使用LifecycleObserver来监听生命周期事件。例如,我们可以定义一个MyLifecycleObserverTest类,实现LifecycleObserver接口,并在其中使用@OnLifecycleEvent注解来标识需要在Activity生命周期发生变化时执行的方法。 为了使用Lifecycle库,我们需要在build.gradle文件中添加相应的依赖。在AndroidX中,我们可以使用implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.0'来引入Lifecycle库。 总结起来,Android的生命周期是指组件在创建、运行和销毁过程中所经历的状态变化。通过使用Lifecycle库,我们可以更方便地管理和监听组件的生命周期,执行一些与生命周期相关的操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值