在 Java 类中调用 Kotlin 挂起函数

2022-08-31 15:01:06

假设我们有以下挂起函数:

suspend fun doSomething(): List<MyClass> { ... }

如果我想在我现有的Java类之一中调用这个函数(我现在无法转换为Kotlin)并获取它的返回值,我必须提供一个作为其参数(显然)。Continuation<? super List<MyClass>>

我的问题是,我该如何实现一个。特别是它的挣脱者。getContext


答案 1

首先,将模块添加到依赖项。在 Kotlin 文件中,定义以下与编写异步 API 的 Java 风格相对应的异步函数:org.jetbrains.kotlinx:kotlinx-coroutines-jdk8

fun doSomethingAsync(): CompletableFuture<List<MyClass>> =
    GlobalScope.future { doSomething() }

现在,从 Java 使用的方式与在 Java 世界中使用其他异步 API 的方式相同。doSomethingAsync


答案 2

如果你不想用,我有一个新想法。org.jetbrains.kotlinx:kotlinx-coroutines-jdk8

在你的 kotlin 项目中编写以下代码。

    @JvmOverloads
    fun <R> getContinuation(onFinished: BiConsumer<R?, Throwable?>, dispatcher: CoroutineDispatcher = Dispatchers.Default): Continuation<R> {
        return object : Continuation<R> {
            override val context: CoroutineContext
                get() = dispatcher

            override fun resumeWith(result: Result<R>) {
                onFinished.accept(result.getOrNull(), result.exceptionOrNull())
            }
        }
    }

我在课堂上写它Coroutines

然后,您可以调用挂起函数,如下所示:

            Coroutines coroutines = new Coroutines();
            UserUtils.INSTANCE.login("user", "pass", coroutines.getContinuation(
                    (tokenResult, throwable) -> {
                        System.out.println("Coroutines finished");
                        System.out.println("Result: " + tokenResult);
                        System.out.println("Exception: " + throwable);
                    }
            ));

login() 函数是一个挂起函数。
suspend fun login(username: String, password: String): TokenResult

对于您的代码,您可以:

doSomething(getContinuation((result, throwable) -> { 
       //TODO
}));

此外,您可能希望在不同的线程(例如主线程)中运行回调代码,只需用于包装launch(Dispathers.Main)resumeWith()


推荐