Kotlin协程-在协程内部调用时如何确保某些命令在UI主线程上运行?

时间:2019-02-23 12:48:22

标签: kotlinx.coroutines

我有一个非常简单的协程,它只会延迟一些时间,然后我要执行的操作是将命令发布到UI消息队列中。因此请在用户界面线程上运行最后两行。这是协程:

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

我希望后两个方法doSomething()和doAnotherThing()在UI线程上运行吗?如何才能做到这一点 ?根据我的阅读,delay(5000)将自动异步运行,但是如何使其余部分在UI线程上运行?非常清楚,我正在从主线程启动的对象中执行此操作。

1 个答案:

答案 0 :(得分:1)

async创建一个协程并在从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()函数返回的Deferred对象上调用async函数。 Here is some additional info