是否正在等待阻塞Android上的UI线程?

时间:2018-12-12 23:34:54

标签: android multithreading kotlin coroutine kotlinx.coroutines

我一直在绕着协程包头,我在想以下代码。 我在 onCreate()上执行以下操作。

asyncJob = GlobalScope.launch(Dispatchers.Main) {
    val name = async(Dispatchers.Default) { queryDevices() }.await()
    mDeviceName.text = deviceName
}

打印出执行顺序似乎在“名称”之前 在UI线程上,并且在设置名称之后,它也在UI线程上。 queryDevicesMethod()在后台线程中符合预期。

但是我想知道 await()在UI线程上调用时实际上在做什么吗? 它会阻塞UI线程直到等待返回吗?

1 个答案:

答案 0 :(得分:7)

协程在挂起时不会阻塞线程。 Kotlin编译器生成一个状态机,该状态机从线程分离和附加协程,请参见https://github.com/Kotlin/kotlinx.coroutines/blob/master/ui/coroutines-guide-ui.md

在您的情况下,GlobalScope.launch(Dispatchers.Main)启动一个局限于UI线程的新协程。然后async()启动一个限制在另一个调度程序中的新协程。 await()的调用是一个挂起函数,它将把第一个协程与UI线程分离,等待async-协程的完成。

顺便说一句: 您不应在一个语句中使用asyncawait。这是没有意义的。 您真正想要的是从另一个调度程序运行queryDevices()函数,但从协程的角度来看不是异步的。在这种情况下,您应该使用withContext()