使用 viewLifecycleOwner 的生命周期范围从 Fragment 启动协程

Posted

技术标签:

【中文标题】使用 viewLifecycleOwner 的生命周期范围从 Fragment 启动协程【英文标题】:Launching a coroutine from a Fragment using viewLifecycleOwner's lifecycleScope 【发布时间】:2021-12-21 17:20:53 【问题描述】:

我正在从 Fragment 启动协程,我的理解是

lifecycleScope.launch 

viewLifecycleOwner.lifecycleScope.launch 

在大多数情况下基本相同。

从 Fragment 内部启动协程时,使用一个比另一个有好处吗?

【问题讨论】:

【参考方案1】:

viewLifecycleOwner.lifecycleScope 只会在片段视图处于有效状态时执行。如果您离开片段,仍在该范围内执行的协程将被取消。而在 lifecycleScope 中启动的协程将完成。

你可以试试下面的代码自己看看。假设这是从 onViewCreated 中的片段 #1 启动的,它会在

val handler = CoroutineExceptionHandler _, exception ->
            println("got $exception")
        
        this.lifecycleScope.launch (handler) 
            try 
                println("LSCOPE: LifecycleOwner.lifecycleScope started")
                delay(5000)
                println("LSCOPE: LifecycleOwner.lifecycleScope completed")
            
            catch(e: CancellationException)
                println("LSCOPE: lifecycleScope cancelled: $e")
            
        

        this.viewLifecycleOwner.lifecycleScope.launch (handler) 
            try 
                println("LSCOPE: viewLifecycleOwner.lifecycleScope started")
                delay(5000)
                println("LSCOPE: viewLifecycleOwner.lifecycleScope completed")
            
            catch(e: CancellationException)
                println("LSCOPE: viewLifecycleOwner.lifecycleScope cancelled: $e")
            
        

在lifeCyclescope成功完成的同时,viewLifecycleOwner.lifecycleScope中启动的协程将被取消;

I/System.out:LSCOPE:viewLifecycleOwner.lifecycleScope 已取消: kotlinx.coroutines.JobCancellationException:作业被取消; job=SupervisorJobImplCancelling@ed6f718

对比:

I/System.out:LSCOPE:LifecycleOwner.lifecycleScope 已完成

那么,有什么好处呢?在旁观者的眼中 - 取决于您的用例:)

【讨论】:

以上是关于使用 viewLifecycleOwner 的生命周期范围从 Fragment 启动协程的主要内容,如果未能解决你的问题,请参考以下文章

使用 viewLifecycleOwner 作为 LifecycleOwner

为啥用 viewLifecycleOwner 观察到的 LiveData 在 onDestroyView 之后会得到回调?

Android 回收站视图更新

espresso 测试“无法访问主线程上的数据库”时出现房间数据库错误

vue中使用keepAlive及使用后生命周期的改变

Android生命周期绑定