【问题标题】:Kotlin coroutine await on UI threadKotlin 协程在 UI 线程上等待
【发布时间】:2019-08-06 07:47:48
【问题描述】:

目前在我的代码库中,使用Kotlin,我有一个扩展函数,它以下列方式工作。

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

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

我想知道是否有办法使用Kotlin coroutines 来实现类似的结果?

我确实实现了这样的东西,但我没有得到很好的性能结果。也许我在 GlobalScope 上运行 await() 函数时做错了什么?

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)
        }
    }
}

【问题讨论】:

    标签: android kotlin kotlin-coroutines


    【解决方案1】:

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

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

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

    【讨论】:

    • 实际上他可以使用async,但这不是他使用的正确async。注意async 返回一个Deferred&lt;T&gt;launch 带回一个JOB
    • 这似乎是一个很好的解决方案,我想我试图过于笼统。我想创建一个函数,你可以在你的 kotlin、android、代码库中的任何地方调用它,它将在后台线程上运行任何操作并将结果传播到 UI 线程,而无需编写太多代码。
    • 我实际上使用的是上面答案中指定的代码,它只是破坏了问题中定义的函数的流程。我还看到Dispatchers.IOwithContext 一起使用时似乎在共享后台线程上运行。
    • 是的,您应该使用 Dispatchers.IO 执行阻塞操作,并使用 Dispatchers.Default 执行 CPU 密集型计算。这些将您的协程转移到后台线程。您可以继续使用 Dispatchers.Main 来暂停异步 IO 等操作或等待事件。
    猜你喜欢
    • 2022-01-18
    • 1970-01-01
    • 1970-01-01
    • 2020-02-22
    • 2019-02-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多