withContext
必须在协程或者suspend
函数中调用,否则会报错。它必须显示指定代码块所运行的线程,它会阻塞当前上下文线程,有返回值,会返回代码块的最后一行的值。
1. 指定代码块所运行的线程
它和launch
一样,通过Dispatchers
来指定代码块所运行的线程,如下所示:
runBlocking<Unit> {
withContext(Dispatchers.IO){
delay(1000)
println("${Thread.currentThread().name} 1")
}
}
2. 阻塞上下文线程
withContext
会阻塞上下文线程,如下所示:
runBlocking<Unit> {
withContext(Dispatchers.IO){
delay(1000)
println("${Thread.currentThread().name} 1")
}
println("${Thread.currentThread().name} 2")
}
结果
DefaultDispatcher-worker-1 @coroutine#1 1
Test worker @coroutine#1 2
从上结果可以看出,withContext
会阻塞上下文线程
3. 有返回值,会返回代码块的最后一行的值
withContext
有返回值,会返回代码块的最后一行的值,如下所示:
runBlocking<Unit> {
val t = withContext(Dispatchers.IO){
delay(1000)
println("${Thread.currentThread().name} 1")
9
}
println("${Thread.currentThread().name} $t")
}
结果:
DefaultDispatcher-worker-1 @coroutine#1 1
Test worker @coroutine#1 9
如果最后一行是无返回值的函数,则它的返回值是最后一行函数的返回值:kotlin.Unit
,代码如下所示:
runBlocking<Unit> {
val t = withContext(Dispatchers.IO){
delay(1000)
println("${Thread.currentThread().name} 1")
}
println("${Thread.currentThread().name} $t")
}
结果:
DefaultDispatcher-worker-1 @coroutine#1 1
Test worker @coroutine#1 kotlin.Unit
总结
withContext
必须在协程或者suspend
函数中调用- 通过
Dispatchers
来指定代码块所运行的线程 withContext
会阻塞上下文线程withContext
有返回值,会返回代码块的最后一行的值