简体   繁体   English

Android Kotlin协程:使用Global范围是否是反模式?

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

This is rather a question for advise then how to. 这是一个问题,然后建议。

I am using viewmodelScope to launch jobs to interact with my database in my ViewModel. 我正在使用viewmodelScope启动作业以与ViewModel中的数据库进行交互。 Some of these jobs can take long and use might navigate away from the Activity/Fragment while job is on going. 其中一些工作可能需要很长时间,并且在工作进行中,使用可能会偏离活动/片段。

I want job to complete no matter what. 无论如何我都希望工作完成。 Is it acceptable to use GlobalScope in this context? 在这种情况下使用GlobalScope是否可以接受?

On first sight GlobalScope looks like a good option to achieve long running operations. 乍一看, GlobalScope似乎是实现长期运行的好选择。 But then you'd run into an issue with the Android lifecycle. 但是随后您会遇到Android生命周期的问题。

Assume you're not bound to it anymore. 假设您不再受此约束。 The moment your global operation is done, you'll unsuspend your callbacks within your Activity or Fragment . 全局操作完成后,您将在ActivityFragment取消暂停回调。 Additionally you'll leak these instances as well. 另外,您还将泄漏这些实例。

Instead you should consider calling your method within a NonCancellable Job : 相反,您应该考虑在NonCancellable Job中调用您的方法:

withContext(NonCancellable) {
    ...
} 

Your code will be canceled just after your long running code completed and cleanup properly. 在长时间运行的代码完成并正确清理之后,您的代码将被取消。

If your calls are completely unrelated to anything from the Android lifecycle, therefore unscoped, just go for GlobalScope . 如果您的呼叫与Android生命周期中的任何事物都不相关,因此不受范围限制,请使用GlobalScope

To quote Roman Elizarov, the Kotlin libraries team lead who works on Coroutines, on this topic : 引用Kotlin图书馆小组负责人Coroutines的Roman Elizarov的话, 该主题是

There is hardly ever reason to use GlobalScope in an application that is based on Kotlin coroutines. 几乎没有理由在基于Kotlin协程的应用程序中使用GlobalScope。

If, as you say, you want the "job to complete no matter what" keep in mind that everything has a scope. 如您所说,如果您希望“无论如何完成一项工作”,请记住, 所有内容都有范围。 Whether it's a fragment, activity or application, everything comes to an end, eventually. 无论是片段,活动还是应用程序,一切最终都将结束。 So the better solution is to use structured concurrency and launch your database job from the scope associated with its work. 因此,更好的解决方案是使用结构化并发,并从与其工作关联的范围中启动数据库作业。

It sounds like that's the activity in your case. 听起来这就是您的情况。 However, if your UI cannot prevent the user from leaving the activity before work is done, and it is critical that the job always completes, then you probably need more than just coroutines. 但是,如果您的UI无法阻止用户在工作完成之前离开活动,并且始终完成工作至关重要,那么您可能需要的不仅仅是协程。 Consider scheduling your long-running work with WorkManager , instead. 考虑使用WorkManager安排您的长期工作。

Either way, try to avoid GlobalScope since it is not the right solution. 无论哪种方式,请尝试避免使用GlobalScope因为它不是正确的解决方案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM