Reputation: 3453
With Kotlin 1.3 one can launch job using GlobalScope.launch
but one thing that I can't seem to figure out is how to keep track of Job
returned by ``GlobalScope.launch` and cancel all pending jobs if they are active.
In older version of launch
one could specify parent = parentJob
and one could simply cancel parentJob. But when using GlobalScope.launch
how does one cancel all pending jobs (easily) so from say ViewModel's onCleared one can cancel all pending stuff.
Upvotes: 1
Views: 1563
Reputation: 30665
Using GlobalScope
is highly discouraged. In the Android KTX libraries there are handy scopes that can be used to launch coroutines. Using them you don't need to think about cancelling jobs, they designed to do it by themselves. CoroutineScope
s:
In ViewModel
class it is viewModelScope
. The CoroutineScope
is bound to Dispatchers.Main
and is automatically cancelled when the ViewModel
is cleared. You can use viewModelScope
instead of creating a new scope for each ViewModel
.
Dependency:
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.4.0"
In Activity
/Fragment
there is lifecycleScope
. Any coroutine launched in this scope is canceled when the Lifecycle
is destroyed. You can access the CoroutineScope
of the Lifecycle
by using the lifecycle.coroutineScope
or lifecycleOwner.lifecycleScope
properties.
Dependency:
implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.4.0"
Example of launching a coroutine in ViewModel
:
viewModelScope.launch {...}
Upvotes: 1
Reputation: 3453
So basically it turns out you can either have your ViewModel/AppComptActivity etc. inherit from CoroutineScope. Or you can use composition like this:
```
private val pendingJobs = Job()
private val coroutineScope = CoroutineScope(contextProvider.io + pendingJobs)
...
...
coroutineScope.launch {
withContext(contextProvider.UI) {
}
}
```
Then in appropriate destroy method call pendingJobs.cancel()
to terminate pending jobs.
Upvotes: 3