2

What is the difference between these two?

I was following a tutorial, and the teacher said we need a scope that lives as long as the app lives, created the scope manually with SupervisorJob. Doesn't GlobalScope do the same thing?

I researched about this, but couldn't find a proper explanation. Thanks.

jane
  • 124
  • 10
  • 1
    Does this answer your question? https://stackoverflow.com/questions/65008486/globalscope-vs-coroutinescope-vs-lifecyclescope – Darshan Sep 23 '22 at 10:33
  • @DarShan no, there is nothing related to SupervisorJob() – jane Sep 23 '22 at 10:36
  • `SupervisorJob` is used so that if one of the `child coroutine` fails, the others are not affected. Without `SupervisorJob`, if one child coroutine fails then all are terminated. – Darshan Sep 23 '22 at 10:39
  • @DarShan that's not the case with GlobalScope? – jane Sep 23 '22 at 10:39

1 Answers1

1

The difference between these two specific examples is that GlobalScope cannot be cancelled, but the other one can. When you call cancel() on a CoroutineScope created with the CoroutineScope() constructor function, all of its children coroutines get canceled.

GlobalScope will throw an IllegalStateException if you try to cancel() it, because it has no Job to be a parent of coroutines that it launches.

When you call CoroutineScope() without passing it a Job, it gets a generic Job automatically to be the parent of its coroutines. A generic parent Job like this will cancel all of its children coroutines if any of them fail. If you explicitly use SupervisorJob(), then if any of its children fail, they won't cause all their siblings to be canceled. This is a behavior that is similar to GlobalScope, since GlobalScope coroutines have no siblings that they could cause to be cancelled through a shared parent.

The reason GlobalScope is discouraged is that it has no supervisory capabilities. It should only be used for coroutines that should run for the entire lifetime of an app session. But if you're doing important work that should not be cancelled on Android, coroutines are not a good choice anyway because they aren't handling the cases where your app is in the background. In those cases you should be using a service or WorkManager instead. So, the actual legitimate use cases for GlobalScope, or any CoroutineScope that is never cancelled, are extremely rare.

I think the reason they added @DelicateCoroutinesApi is that so many people were misusing GlobalScope. (Probably because they unfortunately used it in the beginner documentation on how to use coroutines.) It is not correct to get around the warning by using CoroutineScope(SupervisorJob()) or CoroutineScope(Dispatchers.IO), etc. instead of GlobalScope, because all that does is mask the warning without changing the behavior other than creating a redundant CoroutineScope. If you have a legitimate use for GlobalScope, you should use @OptIn(DelicateCoroutinesApi::class) to dismiss the warning.

Tenfour04
  • 83,111
  • 11
  • 94
  • 154
  • Except for being uncancellable, what should stop me from using GlobalScope, if I want to have a scope that lives as long as the app does? – jane Sep 23 '22 at 13:50
  • 1
    I added a paragraph explaining it. Coroutines won't handle background state of your app very well. If you're just logging something periodically, it's fine and you should go ahead and use it. If you're doing something critical like processing a large video file before saving it, coroutines are not suitable at all, with or without GlobalScope. – Tenfour04 Sep 23 '22 at 13:55
  • I got it now. Thank you for your time! – jane Sep 23 '22 at 13:59