java - 如何从 Java 7 调用 Kotlin 挂起协程函数

标签 java android kotlin coroutine kotlinx.coroutines

我正在尝试从 Java 7 调用 Kotlin 函数。我正在使用协程,这个被调用的函数正在挂起,例如:

suspend fun suspendingFunction(): Boolean {
    return async { longRunningFunction() }.await()
}

suspend fun longRunningFunction() : Boolean {
    delay(400)
    return true
}

我在 0.25.3 版本中使用协程,我可以通过传递 Continuation<U> 来模拟简单的 Java 回调样式。实例作为挂起函数的参数,例如

CoroutinesKt.suspendingFunction(new Continuation<Boolean>() {
    @Override
    public CoroutineContext getContext() {
        return EmptyCoroutineContext.INSTANCE;
    }

    @Override
    public void resume(Boolean value) {
        doSomethingWithResult(value);
    }

    @Override
    public void resumeWithException(@NotNull Throwable throwable) {
        handleException(throwable);
    }
});

但是,在更新到完全稳定的 1.0.1 版本后,我认为它不再可能了。假设暂停功能的更新版本如下所示:

suspend fun suspendingFunction(): Boolean {
    return GlobalScope.async { longRunningFunction() }.await()
}

Continuation<U>现在使用 Result类,这似乎无法从 Java 中使用(这是有道理的,因为它是内联类)。我试图使用 Continuation 的一些子类来自协程,但它们都是内部的或私有(private)的。

我知道通常是 advised to transform coroutine to CompletableFuture ,但我在 Android 上,这意味着仅 Java 7。简单 Future另一方面太笨了,因为我不想定期检查函数是否完成 - 我只想在它完成时被调用。而且我真的很想避免添加新库或许多其他类/方法。

有没有什么简单的方法可以直接从 Java 7 调用挂起函数?

由于 Kotlin 试图与 Java 实现非常好的互操作性,我想会有一些简单的方法来做到这一点,但我还没有找到。

最佳答案

根据您的环境,您有多种选择。

  1. 如果您在项目中使用 RxJava2,则模块 kotlinx-coroutines-rx2 具有在协程和 Rx 数据类型之间来回转换的实用函数。

示例

suspend fun sayHello(): String {
    delay(1000)
    return "Hi there"
}

fun sayHelloSingle(): Single<String> = GlobalScope.rxSingle { sayHello() }
  1. 否则,您可以添加一个新的 Continuation 类,该类与旧类的定义相匹配,并且在 Java 端也很有用。

示例(Kotlin 方面)

abstract class Continuation<in T> : kotlin.coroutines.Continuation<T> {
    abstract fun resume(value: T)
    abstract fun resumeWithException(exception: Throwable)
    override fun resumeWith(result: Result<T>) = result.fold(::resume, ::resumeWithException)
}   

示例(Java 端)

sayHello(new Continuation<String>() {
    @Override
    public CoroutineContext getContext() {
        return EmptyCoroutineContext.INSTANCE;
    }

    @Override
    public void resume(String value) {
        doSomethingWithResult(value);
    }

    @Override
    public void resumeWithException(@NotNull Throwable throwable) {
        doSomethingWithError(throwable);
    }
});

关于java - 如何从 Java 7 调用 Kotlin 挂起协程函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54022921/

相关文章:

java - 如何修复 "MissingBackpressureException"

java - 在 MySQL 中插入来自 java 的日期时间字符串

android - 如何查询 firebase 节点的所有子节点?

android - 我如何在 Android Studio 中添加依赖项

java - 使用 BigInteger 查找 200 位素数

list - Kotlin 中的函数式编程 : Counting elements in list by using fold

java - JSON如何反序列化数组?

java - 如何知道消息是否已读

android - 如何从 Ubuntu 的终端在 Android Studio 中打开一个已经创建的项目?

android - fragment 中的mapView.onCreate(savedInstanceState)