在 CoroutineScope 和 launch 中作为参数的 Job 有什么不同?

J.D*_*gon 5 kotlin kotlin-coroutines

这两个代码运行完全相同。将作业放入 CoroutineScope 和启动有何不同?

private val job = CoroutineScope(Dispatchers.Main).launch(start = CoroutineStart.LAZY) {
    for(i in 10 downTo 0) {
        Log.d("test", ": $i")
        delay(1000)
    }
}

CoroutineScope(Dispatchers.Main+job).launch{ }

CoroutineScope(Dispatchers.Main).launch(job) { }
Run Code Online (Sandbox Code Playgroud)

Mar*_*nik 6

从技术上讲,两者都会导致相同的行为,但要点是,这两种方法都不是使用CoroutineScope()。这是写同样的东西的惯用方式:

\n
GlobalScope.launch(Dispatchers.Main+job) { ... }\n
Run Code Online (Sandbox Code Playgroud)\n

如果这引起了您的注意(“不要使用 GlobalScope! ”),那是因为它应该 \xe2\x80\x94 您的示例只是犯同样错误的另一种方式,具有更详细的代码。您构造 aCoroutineScope而不持有对它的引用,从而产生与GlobalScope

\n

此外,使用Job作为实际协程句柄的实例的方式也是错误的:与协程作用域关联的作业应该是从或返回的独立Job()实例SupervisorJob()。它的唯一目的是作为取消整个范围或检查其状态的中心点。

\n

  • 像“val rootScope = CoroutineScope(Dispatchers.Main + Job())”这样的东西,相当于较短的“CoroutineScope(Dispatchers.Main)”,因为如果缺少,它会添加一个“Job()”。然后,当您想取消工作时,请使用 rootScope.coroutineContext.job.cancel() (2认同)