簡體   English   中英

帶有 Kotlin 協程的函數是否可以等待完成並返回 Java 類?

[英]Is it possible for a function with a Kotlin coroutine to wait for completion and return to a Java class?

我正在開發基於 Java 的 Android 應用程序。 我想開始在主線程之外使用 Kotlin 和協程進行與網絡相關的工作,但我遇到了一個問題,試圖弄清楚如何成功處理某種情況。

我已經創建了一個帶有網絡功能的 Kotlin 文件,我計划在 Java 類(一個視圖模型,目前需要用 Java 編寫)中調用它。 這個想法是我希望網絡功能修改並將列表返回給視圖模型,然后允許視圖模型繼續進行。

fun performNetworking(
    data: MutableList<Data>
): MutableList<Data> {
    CoroutineScope(Dispatchers.IO).launch {
        data.forEach {
            // modify each element in the list
        }
    }
    return data
}

目前,我從 Java 視圖模型中調用它,如下所示:

    public void modifyData(List<Data> data) {
        List<Data> modifiedData = NetworkingKt.performNetworking(data);
        performMoreThings(modifiedData);
    }

使用此實現, performMoreThings()會觸發,就好像列表中的任何數據都沒有被修改一樣。 通過調試,我發現在協程作用域可以做任何事情之前, performMoreThings()的結論是用未修改的Data列表。

因此,我想知道是否有辦法讓代碼在將數據列表返回到 Java 視圖模型之前等待協程范圍的工作完成(不鎖定主線程並阻止用戶與應用程序交互)? 還是我誤解了協程的能力、目的和實現,這是不可能的? 我是否必須傳入對視圖模型的引用,並在協程完成后讓它調用延續方法,就像我在onPostExecute()使用 AsyncTask 所做的那樣?

不,這是不可能的。 不是因為協程的限制,而是相反 - 由於非協程代碼的限制。 您的modifyData()是一個常規的、不可modifyData()方法,因此它無論如何都不能在不阻塞線程的情況下等待。 Kotlin 的掛起函數可以做到這一點,但 Java 方法不能。

您需要從后台線程調用modifyData() ,因此阻塞不會成為問題,或者重新設計performNetworking()以使用處理異步任務的經典技術之一,即接收回調或返回未來:

fun performNetworking(
    data: MutableList<Data>
): CompletableFuture<MutableList<Data>> {
    return CoroutineScope(Dispatchers.IO).future {
        data.forEach {
            // modify each element in the list
        }
        data
    }
}
public void modifyData(List<Data> data) {
    NetworkingKt.performNetworking(data)
            .thenAccept(this::performMoreThings);
}

暫無
暫無

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

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