I'm trying to understand the difference between the 2.
If a CoroutineScope is not tied to any lifecycle-aware component, then I think they behave the same:
If Im not passing any context to CoroutineScope, then both would initialized with EmptyCoroutineContext, and thats practicaly means children has no parents, meaning they run totaly independently, and not even scope.cancel() actualy cancels them, and thats only happen when the whole app is closed. Am I missing something here ?
val scope = GlobalScope()
scope.launch {
launch {
println("job1 working")
}
launch {
println("job2 working")
}
}
scope.cancel() // no any effect
val scope = CoroutineScope(EmptyCoroutineContext)
...
scope.cancel()
If my understanding is correct, are there any example where they different ?
Yes, there are significant differences between GlobalScope and CoroutineScope in Kotlin coroutines.
GlobalScope is a top-level, lifecycle-unaware scope. Coroutines launched using GlobalScope.launch are not tied to any specific component or parent job and live as long as the entire application process runs.
GlobalScope.launch returns only a Job instance, not a scope. While calling cancel() on that job should cancel it and its child jobs, you may not observe the cancellation effect because each of those child jobs has already completed before the cancel() call takes effect.
You create a scope using CoroutineScope(EmptyCoroutineContext). Passing EmptyCoroutineContext means the scope uses the default dispatcher (Dispatchers.Default). Since this is a CoroutineScope, any coroutine launched with scope.launch can be cancelled by calling scope.cancel().