簡體   English   中英

返回值(Int) from Kotlin coroutine from Java call

[英]Returning value (Int) from Kotlin coroutine from Java call

我一直在努力將值從 Kotlin 協程返回到 Java,感覺時間太長了。 這就是我最終讓它工作的方式,但我不是 100% 確定這是最好的方式。 返回 Kotlin 時獲取返回值的方法不起作用。 我只是用 SQLite 數據庫中的總行數更新 UI。

這是我從主線程 Java(活動)打來的電話

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

這是 DbUtil 中的方法(Kotlin object 類)

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

我的問題:

  1. 添加 withContext(IO) 是否可以防止主線程被阻塞?
  2. 如果這確實阻塞了,我該如何重寫它以使其不阻塞。

使用 runBlocking 會按照它說的去做,阻塞結果。 所以調度到 IO 調度器沒有效果。

掛起的 function 只能由協程調用,因此您必須在協程內才能調用任何可掛起的 function。

  1. 首先移除障礙,即使 function 可從非協程主體調用:
@JvmStatic
val scope = CoroutineScope(EmptyCoroutineContext)

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

如果您在協程中(在 Kotlin 代碼中),您可以簡單地調用.await()來獲取 Int 結果(掛起)。

  1. 要使結果與 Java 互操作,您可以將 Deferred 從協程轉換為 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. 然后你可以使用回調風格來收聽結果:
cf.whenCompleteAsync((result, exception) -> {
    // Ensure UI change happens on Main/UI thread.
    new Handler(context.getMainLooper()).post(() -> tv.setText(String.valueOf(result)));
});

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM