CrotoutineName 用于为 Coroutine 命名,主要用于 debug。coroutineContext[CoroutineName] 这种写法来自于 Kotlin 对于 companion object 的简便写法,等价于 coroutineContext[CoroutineName.Key], Key 的定义为 CoroutineContext.Key<CoroutineName>,也就是 coroutineContext.get(key: Key<E>) 的参数。
fun main() {
val coroutineScope = CoroutineScope(CoroutineName("outer coroutine"))
coroutineScope.launch {
// // coroutineContext 来自于 lambda block 的 receiver - CoroutineScope
println(coroutineContext[CoroutineName].toString()) // 1
withContext(Dispatchers.IO) {
println(coroutineContext[CoroutineName].toString()) // 2
}
withContext(CoroutineName("inner coroutine")) {
println(coroutineContext[CoroutineName].toString()) // 3
}
println(coroutineContext[CoroutineName].toString()) // 4
}
Thread.sleep(100)
}
运行结果如下:
CoroutineName(outer coroutine) CoroutineName(outer coroutine) CoroutineName(inner coroutine) CoroutineName(outer coroutine) |
part1 在 launch 内从 coroutineContext 中取出 CrotoutineName 是我们构造时传入的。part2 我们通过 withContext 传入 Dispatchers.IO,取出的 CrotoutineName 并未发生变化。part3 在传入新的 CoroutineName("inner coroutine") 之后取出的 CrotoutineName 就变成了新传入的。withContext 会继承外部 Coroutine 的 CoroutineContext(withContext 并不是只能用来流转任务到其他线程,本质是使用传入的参数改变其后面的 Coroutine 的 CoroutineContext,这便是其名字的由来)withContext 后面的 Coroutine 的 CoroutineContext 会使用传入的参数覆盖对应的 Key 的值。从 part4 可以看出,withContext 传入的 CoroutineContext 只会影响后面的 Coroutine,不会影响到外部