首页 > 解决方案 > 暂停协程直到任务的正确方法已经完成

问题描述

我最近涉足 Kotlin 协程 因为我使用了很多 Google 的库,所以大部分工作都是在Task类中完成的

目前我正在使用这个扩展来暂停协程

suspend fun <T> awaitTask(task: Task<T>): T = suspendCoroutine { continuation ->
    task.addOnCompleteListener { task ->
        if (task.isSuccessful) {
            continuation.resume(task.result)
        } else {
            continuation.resumeWithException(task.exception!!)
        }
    }
}

但最近我看到了这样的用法

suspend fun <T> awaitTask(task: Task<T>): T = suspendCoroutine { continuation ->
    try {
        val result = Tasks.await(task)
        continuation.resume(result)
    } catch (e: Exception) {
        continuation.resumeWithException(e)
    }
}

有什么区别,哪一个是正确的?

UPD:第二个示例不起作用,我知道为什么

标签: androidkotlintaskkotlin-coroutinessuspend

解决方案


传递给的代码块suspendCoroutine { ... }不应阻塞正在调用它的线程,从而允许挂起协程。这样,实际线程可以用于其他任务。这是一个关键特性,它允许 Kotlin 协程甚至在单个 UI 线程上扩展和运行多个协程。

第一个示例正确执行,因为它调用task.addOnCompleteListener(请参阅文档)(它只是添加一个侦听器并立即返回。这就是第一个正常工作的原因。

第二个示例使用Tasks.await(task)(请参阅文档)阻塞正在调用它的线程并且在任务完成之前不会返回,因此它不允许协程被正确挂起。


推荐阅读