I'm trying to call Kotlin function from Java 7. I'm using coroutines and this called function is suspending, for example:
suspend fun suspendingFunction(): Boolean {
return async { longRunningFunction() }.await()
}
suspend fun longRunningFunction() : Boolean {
delay(400)
return true
}
I was using coroutines in version 0.25.3 and I could emulate simple Java callback style by passing Continuation<U>
instance as an argument to suspending function, e.g.
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);
}
});
However, after updating to fully stable 1.0.1 release, I think it's no longer possible. Let's say updated version of suspending function looks like that:
suspend fun suspendingFunction(): Boolean {
return GlobalScope.async { longRunningFunction() }.await()
}
Continuation<U>
now uses Result
class, which seems to be unusable from Java (which makes sense as it is inline class). I was trying to use some subclass of Continuation
from coroutines but they are all internal or private.
I know that usually it is advised to transform coroutine to CompletableFuture
, but I'm on Android, which means Java 7 only. Simple Future
on the other hand is too dumb as I don't want to check periodically if function is finished - I just want to be called when it is finished. And I would really like to avoid adding new libraries or many additional classes/methods.
Is there any simple way to call suspending function directly from Java 7?
As Kotlin tries to be very interoperable with Java I would imagine there would be some easy way to do that, but I'm yet to find it.
You have several options depending on your environment.
RxJava2
in the project, the module kotlinx-coroutines-rx2
has utility functions to convert back and forth between coroutines and Rx datatypes.Example
suspend fun sayHello(): String {
delay(1000)
return "Hi there"
}
fun sayHelloSingle(): Single<String> = GlobalScope.rxSingle { sayHello() }
Continuation
class that matches the definition of the old one and is also useful in the Java side.Example (Kotlin side)
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)
}
Example (Java side)
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);
}
});