如果您将代码更改为:
override fun onResume() {
super.onResume()
lifecycleScope.launch(Dispatchers.Main.immediate) {
println(1)
delay(3000)
println(2)
}
println(3)
}
...那么你就会更接近你的预期输出--至少在Kotlin/JS,你会得到1
,然后是3
,然后是2
.
Dispatchers.Main.immediate
和Dispatchers.Main
之间的差异与Activity
上的runOnUiThread()
和View
上的post()
之间的差异非常相似.这两个方法都采用Runnable
并在主应用程序线程上运行该Runnable
.但是,主应用程序线程主要工作是执行发送到工作队列的工作.
Dispatchers.Main
会将协程放在工作队列中.那个协程要到一段时间以后才会运行.由于onResume()
是在主应用程序线程上调用的,并且协程将在稍后运行,因此println(3)
首先执行.
Dispatchers.Main.immediate
表示"如果我们的代码在主应用程序线程上执行,则立即运行协程",这与runOnUiThread()
非常相似.由于onResume()
是在主应用程序线程上调用的,因此至少println(1)
会在println(3)
之前被调用.
UPDATE: 2023-09-22:Dispatchers.Main
和Dispatchers.Main.immediate
的实际实现是特定于平台的,这可能会影响delay()
的处理方式.在Kotlin/JS上(可能在基于Ian Lake's comment的Kotlin/JVM中),delay()
将调度协程的其余部分稍后运行并释放当前线程.这允许主应用程序线程在launch()
调用之后继续处理,因此println(3)
发生了,println(2)
发生在3秒标记处.您可能希望在其他Kotlin多平台目标中测试该行为,以确保它在那里同样有效.