The entire level of getting these Android pre-defined coroutine scopes is it routinely cancels all of the coroutines which can be launched on this scope, so that you need not explicitly cancel them. The exception is GlobalScope
survives till course of demise.
GlobalScope
GlobalScope
by no means will get canceled, even when the exercise is destroyed/completed. For those who launch a coroutine with GlobalScope
, the coroutine runs till it ends. If the coroutine does not finish, it’ll maintain operating both within the background or foreground till the method is killed.
GlobalScope.launch {
}
That is similar to while you create your individual customized CoroutineScope
. The customCoroutineScope
won’t be cancelled except you express cancel it.
val customCoroutineScope = CoroutineScope(Dispatchers.Most important)
customCoroutineScope.launch {
}
Utilizing GlobalScope or create
your individual customized CoroutineScope
just isn’t advisable. 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 demise (e.g. killed by the working system)
viewModelScope
You’ll be able to entry the viewModelScope
in ViewModel
. As you possibly can 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 it is going to 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
will be sure to the lifecycles of the Exercise or the Composable perform.
For those who use lifeCycleScope
within the Exercise, the scope is sure 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 {
}
}
}
For those who use lifeCycleScope
in a composable perform (the place the composable perform just isn’t a composable vacation spot, which means when compose navigation is NOT used), the lifeCycleScope
is sure 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 perform, you utilizeLocalLifecycleOwner.present.lifecycleScope
Nonetheless, if the composable perform is a composable vacation spot (i.e. when compose navigation is used), the lifeCycleScope
is sure to the lifecycle of the composable perform (i.e. DemoScreen()
).
Just like the lifecycle of ViewModel, when the composable perform is popped out from the again stack (faraway from the again stack), the lifeCycleScope
is canceled. If the composable perform stays within the again stack, all coroutines belong to this lifeCycleScope
won’t be canceled.
rememberCoroutineScope
rememberCoroutineScope
is a composable perform that creates a CoroutineScope
that bounds to its composable perform.
@Composable
enjoyable DemoScreen() {
val rememberCoroutineScope = rememberCoroutineScope()
Button(onClick = {
rememberCoroutineScope.launch {
}
})
}
On this instance, when DemoScreen
leaves the composition, all coroutines belong to this scope
shall be canceled.
The next situations trigger the composable perform leaves the composition:
Please word that placing the app to the background (e.g. urgent the house button) does not trigger
DemoScreen()
leaves the composition.
What about non-cancellable coroutines?
Non-cancellable coroutines is unhealthy. Since coroutine cancellation is cooperative, there is no such thing as a means you possibly can 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 demise |
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 perform 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.
Eventualities | 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 from side to side
When the app strikes to the background, each lifeCycleScope
and rememerCoroutineScope
will not be canceled.
The truth is, all these pre-defined coroutine scopes are losing assets and reminiscence as a result of it retains operating within the background although there is not something to replace on the UI.
The options could possibly be utilizing lifeCycleScope.launchWhenStarted()
or lifecycle.repeatOnLifeCycle().
See the next article for particulars:
lifeCycleScope.launchWhenResumed()
just isn’t supreme 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.