Kotlin协程在UI线程上等待

时间:2019-08-06 07:47:48

标签: android kotlin kotlin-coroutines

目前,在我的代码库中,我使用Kotlin有一个扩展功能,该功能可以按以下方式工作。

async {
    executeSomeCodeToGetResult()
}.awaitOnUiThread { result ->
    useResultOnUiThread(result)
}

async函数将可运行对象加载到ExecutorService上,该结果返回Future<T>的结果。 awaitOnUiThreadFuture<T>对象上的扩展函数,它将T作为参数发送给输入函数。

我想知道是否有一种方法可以使用Kotlin coroutines来达到类似的结果?

我确实实现了类似的方法,但是没有得到很好的性能结果。也许我在await()上运行GlobalScope函数时做错了吗?

private const val threadPoolSize = 4

@ObsoleteCoroutinesApi
val scope = CoroutineScope(newFixedThreadPoolContext(threadPoolSize, "async-runner"))

@ObsoleteCoroutinesApi
fun <T> async(function: () -> T): Deferred<T> {
    return scope.async { function() }
}

fun <T> Deferred<T>.awaitOnUiThread(function: (T) -> Unit) {
    val deferred = this
    GlobalScope.launch {
        val result: T = deferred.await()
        Handler(Looper.getMainLooper()).post {
            function(result)
        }
    }
}

1 个答案:

答案 0 :(得分:3)

使用协程,您不需要asyncawaitOnGuiThread中的任何一个。您应该使用以下成语:

launch(Dispatchers.Main) {
    val result = withContext(Dispatchers.IO) {
        executeSomeCodeToGetResult()
    }
    ... just keep using the result
}

至少这是一个大概的近似值。 Kotlin的协程系统希望您也明确处理失败和取消。该主题的名称为structured concurrency。最好的起点是ViewModel,因为它有built-in support用于结构化并发。