I am creating a coroutine using the script below:

fun bar(completion: () -> Unit) {
  GlobalScope.launch(Dispatchers.IO) {
    val lambda = {
      withContext(Dispatchers.Main) { //Suspension functions can be called only within coroutine body
        completion()
      }
    }
    foo(lambda)
  }
}

fun foo(lambda: () -> Unit) {
  //...do something heavy
  lambda()
}

But I am getting the error Suspension functions can be called only within coroutine body when I call withContext(Dispatchers.Main) because the lambda changes the context. I cannot change foo(lambda: () -> Unit) to foo(lambda: suspend () -> Unit) because it's from an external library.

Any idea of what I can do to call withContext(Dispatchers.Main) inside the lambda created inside the launch context?

  • Kotlin version: 1.3.41
  • Coroutines: 1.3.0-RC

非常感谢.

推荐答案

You can rewrite your bar function like this:

fun bar(completion: () -> Unit) {
    GlobalScope.launch(Dispatchers.IO) {
        suspendCoroutine<Unit> {
            val lambda = {
                it.resume(Unit)
            }
            foo(lambda)
        }
        withContext(Dispatchers.Main) {
            completion()
        }
    }
}

Kotlin相关问答推荐

Ktor错误:未指定端口或sslPort

我可以检测一个函数是否在Kotlin中被递归调用(即,重入)吗?

捕捉异常是Kotlin协程中的反模式吗?

Kotlin SIZE_BYTES

TzdbZoneRulesProvider 在 java.time 中不工作

Kotlin 可空泛型

如何使用函数类型或 lambdas 作为 Kotlin 上下文接收器的类型?

在 Kotlin 中,为什么在 `+` 之前但在 `.` 之前没有换行符?

如何从 kotlin 中的数据类访问 val?

关于 Kotlin 函数类型转换的问题

如何用 kotlin 打包 List

使用 Kotlin 创建新目录,Mkdir() 不起作用

变量后的Android问号

如何在顶级函数中使用 koin 注入依赖项

作为 Kotlin 中的函数的结果,如何从 Firestore 数据库返回列表?

如何将map函数应用于Kotlin中的数组并更改其值?

android Room 将 Null 作为非 Null 类型返回

如何限制kotlin协程的最大并发性

在 Kotlin 中返回函数有不那么丑陋的方法吗?

如何在Kotlin中将字符串转换为InputStream?