首页 > 解决方案 > 如何从 Java 调用协程(暂停函数和流)?

问题描述

我决定写这个问题,因为还没有关于这个主题的最佳实践。

我们正在提供一个 Android SDK,它使用 Coroutines 实现异步调用。我希望我们的客户使用FlowJava 或标准 Kotlin 的挂起函数。

我知道有kotlinx-coroutines-jdk8但这只能从 Android Api 级别 24 使用,我们的 SDK 支持 Android 到 Api 级别 21。所以目前这不是一个选项。

我的想法是通过提供一个简单的回调 API 来连接 Java(或标准 Kotlin)和 Coroutines 的世界。

我想知道我的以下方法是否是一个好的解决方案。有什么缺点或危险吗?我必须让客户调用 Coroutines 函数而不强迫他们自己使用 Coroutines 有什么选择?

现在让我们开始吧。首先,我向您展示了一些接口和辅助函数,稍后我可以使用这些接口和辅助函数来映射挂起函数和 Flow。

消除

我需要确保可以从 Java 中取消 Coroutine。所以我创建了一个Cancelable界面。

interface Cancelable {
  fun cancel()
}

该接口由CancelableJob包含并隐藏Job要取消的对象实现。

class CancelableJob(private val job: Job) : Cancelable {
  override fun cancel() {
    job.cancel()
  }
}

启动一个新的协程

每次客户调用一个函数时,我都会启动一个新的协程。为此,我创建了一个顶级函数launchCancelableJob。此函数获取一个暂停块并返回一个Cancelable. Coroutine 将在 上启动Dispatchers.Main,因此所有结果都可以在 UI Thread 上观察到,以及SupervisedJob.

fun launchCancelableJob(block: suspend () -> Unit): Cancelable {
  val job: Job = CoroutineScope(Dispatchers.Main + SupervisorJob()).launch {
    block.invoke()
  }

  return CancelableJob(job)
}

将挂起函数和流程桥接到 Java 世界

现在是时候提供一个桥接函数了,它本身不是挂起函数,而是启动协程并返回一个Cancelable. 从给定的回调中,结果将被传递给调用者。

// normal coroutine api
suspend fun generateQrCode(): QrCode

// bridge function - to be called from Java
fun generateQrCode(callback: (QrCode) -> Unit): Cancelable {
  return launchCancelableJob {
    val qrCode: QrCode = generateQrCode()
    callback(qrcode)
  }
}

我可以对 Flow 做同样的事情。

// normal coroutine api
fun generateQrCodes(): Flow<QrCode>

// bridge function - to be called from Java
fun generateQrCodes(callback: (QrCode) -> Unit): Cancelable {
  return launchCancelableJob {
    generateQrCodes().collect { qrCode: QrCode ->
      callback(qrcode)
    }
  }
}

用法

上面的函数可以从 Java 中调用,例如:

Cancelable cancelable = generateQrCode(new Function1<QrCode, Unit>() {
  @Override
  public Unit invoke(QrCode qrCode) {
    // show the qrCode
    return Unit.INSTANCE;
  }
});

如果不再需要它可以被取消,如:

cancelable.cancel();

这是我的方法。我真的很期待您的意见或更好的解决方案。感谢您的阅读,我知道这是一个很长的问题。

标签: javakotlinkotlin-coroutines

解决方案


推荐阅读