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

sty*_*972 9 android android-lifecycle android-fragments kotlin-coroutines

我正在从片段启动协程,并且我了解到

lifecycleScope.launch {}
Run Code Online (Sandbox Code Playgroud)

viewLifecycleOwner.lifecycleScope.launch {}
Run Code Online (Sandbox Code Playgroud)

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

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

Dmi*_*tri 9

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

您可以尝试以下代码来亲自查看。假设这是从onViewCreated中的片段 #1 启动的,它会在 5 秒内自动移动到片段 #2。

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")
            }
        }
Run Code Online (Sandbox Code Playgroud)

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

I/System.out: LSCOPE: viewLifecycleOwner.lifecycleScope 已取消:kotlinx.coroutines.JobCancellationException:作业已取消;作业=SupervisorJobImpl{取消}@ed6f718

对比:

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

那么,有什么好处呢?情人眼中 - 取决于您的用例:)