Assume we have the following suspend function:
suspend fun doSomething(): List<MyClass> { ... }
If I want to call this function in one of my existing Java classes (which I'm not able to convert to Kotlin for now) and get its return value I have to provide a Continuation<? super List<MyClass>>
as its parameter (Obviously).
My question is, How can I implement one. Specially its getContext
getter.
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.
Kotlin has been designed from the beginning to fully interoperate with Java, and both JetBrains and Google have pushed in that direction. For instance, IntelliJ and Android Studio allow users to convert files from Java to Kotlin. The conversion is not always problem-free, but it generally does a good job.
We just have to use the suspend keyword. Note: Suspend functions are only allowed to be called from a coroutine or another suspend function. You can see that the async function which includes the keyword suspend. So, in order to use that, we need to make our function suspend too.
You can implement "coroutines" as threads/thread pools behind the scenes. You can do tricksy things with JVM bytecode behind the scenes to make coroutines possible. The so-called "Da Vinci Machine" JVM implementation has primitives that make coroutines doable without bytecode manipulation.
First, add org.jetbrains.kotlinx:kotlinx-coroutines-jdk8
module to your dependencies. In your Kotlin file define the following async function that corresponds to Java style of writing async APIs:
fun doSomethingAsync(): CompletableFuture<List<MyClass>> = GlobalScope.future { doSomething() }
Now use doSomethingAsync
from Java in the same way as you are using other asynchronous APIs in the Java world.
If you dont want to use org.jetbrains.kotlinx:kotlinx-coroutines-jdk8
, I have a new idea.
Write below code in your kotlin project.
@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()) } } }
I write it in my Coroutines
class
Then you can call your suspend function like:
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() function is a suspend function.suspend fun login(username: String, password: String): TokenResult
For your code, you can:
doSomething(getContinuation((result, throwable) -> { //TODO }));
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