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.
Java Thread suspend() methodThe suspend() method of thread class puts the thread from running to waiting state. This method is used if you want to stop the thread execution and start it again when a certain event occurs. This method allows a thread to temporarily cease execution.
A coroutine is a concurrency design pattern that you can use on Android to simplify code that executes asynchronously. Coroutines were added to Kotlin in version 1.3 and are based on established concepts from other languages.
Java, as slow adopter of new concepts is getting structured concurrency as part of the Loom project. This addition enables native support for coroutines (termed virtual threads) in Java.
If you notice the functions closely, they can be used to resume the coroutine with a return value or with an exception if an error had occurred while the function was suspended. This way, a function could be started, paused, and resume with the help of Continuation. We just have to use the suspend keyword.
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);
}
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With