Android Kotlin Coroutines:使用全局范围是一种反模式吗?

Android Kotlin Coroutines: Is using Global scope an anti-pattern?

这是一个建议而不是如何做的问题。

我正在使用 viewmodelScope 启动作业以与我的 ViewModel 中的数据库进行交互。其中一些作业可能需要很长时间,并且在作业进行时使用可能会离开 Activity/Fragment。

无论如何我都想完成工作。在这种情况下使用 GlobalScope 是否可以接受?

乍一看,GlobalScope 看起来是实现长 运行ning 操作的好选择。但是你 运行 会遇到 Android 生命周期的问题。

假设您不再受其约束。全局操作完成后,您将取消挂起 ActivityFragment 中的回调。此外,您还会泄露这些实例。

相反,您应该考虑在 NonCancellable Job:

中调用您的方法
withContext(NonCancellable) {
    ...
} 

您的长 运行ning 代码完成并正确清理后,您的代码将被取消。

如果您的调用与 Android 生命周期中的任何内容完全无关,因此没有作用域,则只需要 GlobalScope.

引用 Kotlin 库团队负责协程的 Roman Elizarov 的话,on this topic

There is hardly ever reason to use GlobalScope in an application that is based on Kotlin coroutines.

如果,如您所说,您想要 "job to complete no matter what" 请记住,一切 都有一个范围。无论是片段、activity 还是应用程序,一切最终都会结束。因此,更好的解决方案是使用 structured concurrency 并从与其工作关联的范围启动数据库作业。

听起来你的情况就是 activity。但是,如果您的 UI 无法阻止用户在工作完成之前离开 activity,并且作业始终完成是至关重要的,那么您可能需要的不仅仅是协程。考虑安排 long-running 与 WorkManager 一起工作。

无论如何,尽量避免GlobalScope,因为它不是正确的解决方案。