弃用警报
此代码使用旧的 Coroutines Api。如果您使用的是 kotlinx-coroutines 1.1.0 或更高版本,则此代码对您没有用处
原来的问题是:
我发现我的 Android 应用程序中的这个特定代码阻止了 UI 线程:
runBlocking {
async(CommonPool) {
Thread.sleep(5000)
}.await()
}
textView.text = "Finish!"
我一直在为几个任务使用协程,它们从不阻塞 UI 线程,如可以在文档中阅读的那样:
. 协程提供了一种避免阻塞线程的方法,并用更便宜、更可控的操作来代替它:暂停协程
但奇怪的是,这段代码:
runBlocking {
async(CommonPool) {
launch(CommonPool) {
Thread.sleep(5000)
runOnUiThread { textView.text = "Finish!" }
}
}.await()
}
表现如预期;不阻塞,等待五秒钟然后打印结果(我需要在之后更新 UI,并且只有在sleep
完成之后)
文档说可以独立使用async
,launch
不需要组合。其实async(CommonPool)
应该够了。
那么这里到底发生了什么?为什么它只适用于async+launch
?
更新(2021 年)
[弃用警告] 此代码使用旧的 Coroutines Api。如果您使用的是 kotlinx-coroutines 1.1.0 或更高版本,请忘记这段代码
我的完整示例代码:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
button1.setOnClickListener {
runBlocking {
async(CommonPool) {
Thread.sleep(5000L)
}.await()
}
textView1.text = "Finally! I've been blocked for 5s :-("
}
button2.setOnClickListener {
runBlocking {
async(CommonPool) {
launch(CommonPool) {
Thread.sleep(5000L)
runOnUiThread { textView1.text = "Done! UI was not blocked :-)" }
}
}.await()
}
}
}
}