The entire level of getting these Android pre-defined coroutine scopes is it mechanically cancels all of the coroutines which are launched on this scope, so that you need not explicitly cancel them. The exception is GlobalScope
survives till course of dying.
GlobalScope
GlobalScope
by no means will get canceled, even when the exercise is destroyed/completed. If you happen to launch a coroutine with GlobalScope
, the coroutine runs till it ends. If the coroutine would not finish, it would hold operating both within the background or foreground till the method is killed.
GlobalScope.launch {
}
That is similar to once you create your individual customized CoroutineScope
. The customCoroutineScope
won’t be cancelled until you express cancel it.
val customCoroutineScope = CoroutineScope(Dispatchers.Essential)
customCoroutineScope.launch {
}
Utilizing GlobalScope or create
your individual customized CoroutineScope
just isn’t really helpful. I am unable to consider any good use case for it.
When your app has exited, the coroutine that launched from
GlobalScope
can nonetheless run within the background till the course of dying (e.g. killed by the working system)
viewModelScope
You possibly can entry the viewModelScope
in ViewModel
. As you’ll be able to inform, this viewModelScope
is scoped to the lifecycle of the ViewModel
. When the ViewModel
is destroyed/cleared, this viewModelScope
is canceled, all of the coroutines from will probably be canceled.
viewModelScope.launch {
}
To grasp the lifecycle of ViewModel
, see the next article:
lifeCycleScope.launch()
Will depend on the place you utilize the lifeCycleScope
, the lifeCycleScope
may be certain to the lifecycles of the Exercise or the Composable operate.
If you happen to use lifeCycleScope
within the Exercise, the scope is certain to the Exercise. It means when Exercise is destroyed, lifeCycleScope.cancel()
is named. All coroutines belonging to this scope are canceled.
class MainActivity : ComponentActivity() {
enjoyable someFunction() {
lifecycleScope.launch {
}
}
}
If you happen to use lifeCycleScope
in a composable operate (the place the composable operate just isn’t a composable vacation spot, that means when compose navigation is NOT used), the lifeCycleScope
is certain to the lifecycle of the Exercise as nicely.
@Composable
enjoyable DemoScreen() {
val lifeCycleScope = LocalLifecycleOwner.present.lifecycleScope
Button(onClick = {
lifeCycleScope .launch {
}
})
}
To retrieve the
LifeCycleCoroutineScope
in a composable operate, you utilizeLocalLifecycleOwner.present.lifecycleScope
Nonetheless, if the composable operate is a composable vacation spot (i.e. when compose navigation is used), the lifeCycleScope
is certain to the lifecycle of the composable operate (i.e. DemoScreen()
).
Much like the lifecycle of ViewModel, when the composable operate is popped out from the again stack (faraway from the again stack), the lifeCycleScope
is canceled. If the composable operate stays within the again stack, all coroutines belong to this lifeCycleScope
won’t be canceled.
rememberCoroutineScope
rememberCoroutineScope
is a composable operate that creates a CoroutineScope
that bounds to its composable operate.
@Composable
enjoyable DemoScreen() {
val rememberCoroutineScope = rememberCoroutineScope()
Button(onClick = {
rememberCoroutineScope.launch {
}
})
}
On this instance, when DemoScreen
leaves the composition, all coroutines belong to this scope
might be canceled.
The next eventualities trigger the composable operate leaves the composition:
Please observe that placing the app to the background (e.g. urgent the house button) would not trigger
DemoScreen()
leaves the composition.
What about non-cancellable coroutines?
Non-cancellable coroutines is unhealthy. Since coroutine cancellation is cooperative, there isn’t any method you’ll be able to cancel it. Thus, unhealthy coroutine implementation could cause execution leakage. The simplest option to overcome that is to make use of kotlinx.coroutines.yield().
Abstract
Pre-defined Coroutine Scopes | When coroutines are cancelled? |
GlobalScope |
By no means till course of dying |
viewModelScope |
ViewModel is destroyed |
lifecycleScope (in Exercise / not in composable vacation spot) |
Exercise is destroyed |
lifecycleScope (in composable vacation spot) |
Composable vacation spot is come out from the again stack |
rememberCoroutineScope |
The composable operate leaves the composition |
lifeCycleScope vs rememberCoroutineScope
When lifeCycleScope
is utilized in composable vacation spot, it behaves form of equally to rememberCoroutineScope
with the next variations.
Situations | lifeCycleScope (composable vacation spot) | rememerCoroutineScope |
Navigate ahead | Coroutines stay (nonetheless within the again stack) | Coroutines are canceled (leaving composition) |
Navigate backward | Coroutines are canceled (faraway from the again stack) | Coroutines are canceled (leaving composition) |
App strikes to background | Coroutines stay (nonetheless within the again stack) | Coroutines stay (nonetheless in composition) |
When lifeCycleScope
(composable vacation spot) is canceled?
When rememerCoroutineScope
is canceled?
- Navigate back and forth
When the app strikes to the background, each lifeCycleScope
and rememerCoroutineScope
will not be canceled.
In truth, all these pre-defined coroutine scopes are losing assets and reminiscence as a result of it retains operating within the background regardless that there is not something to replace on the UI.
The options might be utilizing lifeCycleScope.launchWhenStarted()
or lifecycle.repeatOnLifeCycle().
See the next article for particulars:
lifeCycleScope.launchWhenResumed()
just isn’t perfect as a result of we nonetheless need to replace the UI when the app is seen within the background.
Supply Code
GitHub Repository: Demo_CoroutineScope
This demo app excludes the
lifeCycleScope
with composable vacation spot.