在下面的例子中。 childJob 是 SupervisorJob 吗?
val viewModelScope: CoroutineScope = CoroutineScope(Dispatchers.Main + SupervisorJob())
val childJob = viewModelScope.launch {/* do something */}
或者类似的东西是必要的:
val viewModelScope: CoroutineScope = CoroutineScope(Dispatchers.Main + SupervisorJob())
val childJob = viewModelScope.launch(SupervisorJob()) {/* do something */}
最佳答案
我会让代码来说话:
fun main() = runBlocking {
val scopeSupervisor = SupervisorJob()
val explicitSupervisor = SupervisorJob()
val explicitPlainJob = Job()
val scope = CoroutineScope(Dispatchers.Main + scopeSupervisor)
scopeSupervisor.printJobClass("scopeSupervisor")
explicitPlainJob.printJobClass("explicitPlainJob")
println()
scope.launch {
coroutineContext.printJobClass("context 1")
scopeSupervisor.printChildren("scopeSupervisor")
}.join()
scope.launch(explicitSupervisor) {
coroutineContext.printJobClass("context 2")
explicitSupervisor.printChildren("explicitSupervisor")
}.join()
scope.launch(explicitPlainJob) {
coroutineContext.printJobClass("context 3")
explicitPlainJob.printChildren("explicitPlainJob")
}.join()
}
fun CoroutineContext.printJobClass(msg: String) {
println("$msg class: ${this[Job]!!.className}")
}
fun Job.printChildren(msg: String) {
println("$msg children: ${children.map { it.className }.joinToString()}")
}
val Any.className get() = this::class.java.simpleName
这会打印
scopeSupervisor class: SupervisorJobImpl
explicitPlainJob class: JobImpl
context 1 class: StandaloneCoroutine
scopeSupervisor children: StandaloneCoroutine
context 2 class: StandaloneCoroutine
explicitSupervisor children: StandaloneCoroutine
context 3 class: StandaloneCoroutine
explicitPlainJob children: StandaloneCoroutine
解读:
范围内的作业和显式传入的作业都不会成为与协程关联的作业。协程作业始终为 StandaloneCoroutine
类型,并且它是传入作业的子级。
另请注意,传入不是作用域作业子级的显式 SupervisorJob
是错误的。如果您取消范围内的顶级作业,这不会传播到您创建的显式 SupervisorJob
。
关于kotlin - 从 CoroutineScope 启动的 Job 和 SupervisorJob 也是一个 SupervisorJob 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59084084/