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:
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.
@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).
// requires: latest $version as of now is 1.3.9
// implementation "org.jetbrains.kotlinx:kotlinx-coroutines-jdk8:$version"
CompletableFuture cf = FutureKt.asCompletableFuture(getDbRowCount());
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.