繁体   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