Cancel all pending Kotlin jobs from ViewModel's onCleared

1.4k views Asked by At

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.

2

There are 2 answers

0
Subodh Nijsure On

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.

0
Sergio On

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. CoroutineScopes:

  • 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 {...}