簡體   English   中英

Kotlin協同程序 - 嵌套協程是在一個協程中處理不同線程的正確方法嗎?

[英]Kotlin Coroutines - Are nested coroutines the proper way to handle different threading within one coroutine?

我正在嘗試使用協程而不是RxJava在基本的網絡調用上第一次看到它是什么樣的,並遇到滯后/線程的一些問題

在下面的代碼中,我正在進行網絡調用userRepo.Login() ,如果發生異常,我會顯示錯誤消息並停止我在函數開始時啟動的進度動畫。

如果我將所有內容保留在CommonPool上(或者不添加任何池),它會崩潰,如果發生異常,則必須在looper線程上完成動畫。 在其他情況下,我收到錯誤,說這必須在UI線程上完成,同樣的問題,不同的線程要求。

我無法在UI線程上啟動整個協同程序,因為登錄調用將阻止,因為它在UI線程上並且弄亂了我的動畫(這是有意義的)。

我能看到解決這個問題的唯一方法是從現有協程中的UI線程上啟動一個新的協同程序,它可以工作,但看起來很奇怪。

這是做事的正確方法,還是我錯過了什么?

override fun loginButtonPressed(email: String, password: String) {

    view.showSignInProgressAnimation()

    launch(CommonPool) {
        try { 
            val user = userRepo.login(email, password)

            if (user != null) {
                view.launchMainActivity()
            }

        } catch (exception: AuthException) {
            launch(UI) {
                view.showErrorMessage(exception.message, exception.code)
                view.stopSignInProgressAnimation()
            }
        }
    }
}

您應該從另一端開始:啟動基於UI的協同程序,從中將重型操作移交給外部池。 選擇的工具是withContext()

override fun loginButtonPressed(email: String, password: String) {
    view.showSignInProgressAnimation()
    // assuming `this` is a CoroutineScope with dispatcher = Main...
    this.launch {
        try {
            val user = withContext(IO) { 
                userRepo.login(email, password) 
            }
            if (user != null) {
                view.launchMainActivity()
            }
        } catch (exception: AuthException) {
            view.showErrorMessage(exception.message, exception.code)
            view.stopSignInProgressAnimation()
        }
    }
}

這樣你就可以保留自然的Android編程模型,它采用GUI線程。

暫無
暫無

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

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