1

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. 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?

1
  • 1
    You can consider WorkManager for the jobs that are not directly connected with your activity/fragment. Commented May 24, 2019 at 10:42

2 Answers 2

5

On first sight GlobalScope looks like a good option to achieve long running operations. But then you'd run into an issue with the Android lifecycle.

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. Additionally you'll leak these instances as well.

Instead you should consider calling your method within a 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.

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks, could you elaborate "Android lifecycle" Do you mean app or activity life cycle by that? My calls not bound to activity lifecycle as they are database calls.
Lifecycle of an Activity or a Fragment. Regarding the binding, the question is, whether or not you use any suspending function from the globally scoped coroutine within the scope which is bound to the lifecycle.
A little bit of attention must be put beforehand if you want to test your GlobalScoped piece of work.
0

To quote Roman Elizarov, the Kotlin libraries team lead who works on Coroutines, on this topic:

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

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. Consider scheduling your long-running work with WorkManager, instead.

Either way, try to avoid GlobalScope since it is not the right solution.

2 Comments

Thanks, I am already using WorkManager for long running batch jobs. It looks like it is best to use use Activity scope.
I see now and then that the WorkManager is particularly designed for deferrable jobs/tasks. In this case, maybe WorkManager is not more ideal than GlobalScope.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.