6

我有一个非常简单的协程,它只是做一些延迟,然后我想要它做的是将命令发布到 UI 消息队列。所以在 UI 线程上运行最后两行。这是协程:

async{
    delay(5000)
    doSomething()
    doAnotherThing()
}

我希望最后两个方法 doSomething() 和 doAnotherThing() 在 UI 线程上运行?如何才能做到这一点 ?从我读过的内容来看,延迟(5000)将自动异步运行,但如何让其余部分在 UI 线程上运行?非常清楚,我是从一个从主线程启动的对象中执行此操作的。

4

1 回答 1

13

async创建一个协程并在协程上下文中运行,继承自 a CoroutineScope,可以使用 context 参数指定其他上下文元素。如果上下文没有任何调度程序或任何其他ContinuationInterceptor,则Dispatchers.Default使用。

如果Dispatchers.Default使用,那么您在构建器中调用的任何函数都async将异步运行。要切换上下文,您可以使用withContext函数:

async {
    delay(5000)
    withContext(Dispatchers.Main) {
        // if we use `Dispatchers.Main` as a coroutine context next two lines will be executed on UI thread.
        doSomething()
        doAnotherThing()
    }
}

如果asyncDispatchers.Main上下文中运行,则不需要切换上下文:

var job: Job = Job()
var scope = CoroutineScope(Dispatchers.Main + job)

scope.async {
    delay(5000) // suspends the coroutine without blocking UI thread

    // runs on UI thread
    doSomething() 
    doAnotherThing()
}

注意async主要用于并行执行。使用一个简单的协程launch构建器来启动。因此,您可以替换async函数示例中的所有launch函数。此外,要使用构建器运行协程,async您需要在函数返回的对象上调用await()函数。这是一些附加信息Deferredasync

于 2019-02-23T13:48:12.607 回答