简体   繁体   中英

Returning value (Int) from Kotlin coroutine from Java call

I've been struggling to return a value from a Kotlin coroutine back to Java for what feels like way too long. This is how I finally got it to work, but am not 100% sure that it is the best way. The ways I get a return value when returning to Kotlin are not working. I'm simply updating the UI with the total row count in the SQLite db.

Here's my call from Java (activity) from main thread

tv.setText(String.valueOf(DbUtil.getDbRowCount()));

And here's the method in DbUtil (Kotlin object Class)

@JvmStatic
fun getDbRowCount(): Int = runBlocking {
    withContext(IO){DbHelper.getInstance().dbRowCount}
}

My questions:

  1. Does adding the withContext(IO) keep the main thread from being blocked?
  2. If this does in fact block, how can I rewrite this so that it doesn't.

Using runBlocking does what it says, blocks for the result. So dispatching to the IO dispatcher has no effect.

A suspending function can only be callable by a coroutine, so you must be inside a coroutine in order to call any suspendable function.

  1. First to remove the barrier, ie to make the function callable from non-coroutine body:
@JvmStatic
val scope = CoroutineScope(EmptyCoroutineContext)

@JvmStatic
fun getDbRowCount(): Deferred<Int> = scope.async(Dispatchers.IO) {
    DbHelper.getInstance().dbRowCount
}

If you are on a coroutine (in Kotlin code) you can simply call .await() to get Int result (suspending).

  1. To make the result interoperable with Java, you can convert the Deferred from the coroutine to a CompletableFuture.
// requires: latest $version as of now is 1.3.9
// implementation "org.jetbrains.kotlinx:kotlinx-coroutines-jdk8:$version"
CompletableFuture cf = FutureKt.asCompletableFuture(getDbRowCount());
  1. Then you can use the callback-style to listen to the result:
cf.whenCompleteAsync((result, exception) -> {
    // Ensure UI change happens on Main/UI thread.
    new Handler(context.getMainLooper()).post(() -> tv.setText(String.valueOf(result)));
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM