弃用警告
此代码使用了旧的协程 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()
}
表现如预期;不会阻塞,等待五秒钟后打印结果(我需要在 sleep
完成后更新 UI)。
文档说可以独立使用 async
和 launch
,它们不需要组合。实际上,async(CommonPool)
就足够了。
那么这里到底发生了什么?为什么只有 async+launch
能够工作?
更新(2021年)
[警告] 此代码使用旧的协程 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()
}
}
}
}