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

Bet*_*eto 1 multithreading android coroutine kotlin kotlinx.coroutines

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

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

将执行顺序打印出来似乎是在UI线程上的“名称”之前,以及在设置名称后,它也在UI线程上。该queryDevicesMethod()是在后台线程预期。

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

Ren*_*ene 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()从另一个调度程序运行-function,但从协程的角度来看不是异步的。在这种情况下,您应该使用withContext()

  • 使用 `async()` 启动一个新的协程,它会返回一个 `Deferred`。`Deferred` 具有 `await` 函数来解析其他协程的结果。通常,您使用 `async/await` 来启动应该并行运行的多个任务。最后收集所有任务的结果。`withContext` 函数用于为某些子任务切换调度器/线程,但您仍然需要按顺序运行(子)任务。因此,一个语句中的“async/await”与“withContext”相同,但不会传达您的意图。 (2认同)