2

Stopping jobs in onCleared() of ViewModel after activity finish shows the JobCancellationException: Job is being canceled and keeps app freeze crash:

What would be the right way to cancel all kotlin coroutines pending jobs from ViewModel's onCleared() in Android

My code inside viewModel:

private val job = SupervisorJob()
private val uiScope = CoroutineScope(Dispatchers.Main + job)

 uiScope.launch {
        try {
            repeat(152212000001) { it ->
                try {
                    Log.d("Timer : ", it)
                    delay(1000)
                } catch (e: Exception) {
                    e.printStackTrace()
                }
            }
        } catch (e: CancellationException) {
            e.printStackTrace()
        }
    }

Inside ViewModel:

override fun onCleared() {
    job.cancel()
    super.onCleared()
}
Nabin
  • 1,451
  • 3
  • 19
  • 26

1 Answers1

4

As per the Easy Coroutines in Android: viewModelScope blog post:

viewModelScope contributes to structured concurrency by adding an extension property to the ViewModel class that automatically cancels its child coroutines when the ViewModel is destroyed.

So by adding a dependency on androidx.lifecycle:lifecycle-viewmodel-ktx:2.1.0-alpha02 (or higher), you'll be able to just use viewModelScope to do the right thing by default:

viewModelScope.launch {
    repeat(152212000001) { it ->
        Log.d("Timer : ", it)
        delay(1000)
    }
}
Blundell
  • 75,855
  • 30
  • 208
  • 233
ianhanniballake
  • 191,609
  • 30
  • 470
  • 443
  • Thanks for your answer. Actually, I was able to cancel the coroutine job but not able to cancel long process child jobs. So, does it immediately cancel the child coroutines after view model destroyed? – Nabin Apr 11 '19 at 05:20
  • Yes, that is the point of structured concurrency. As long as you don't mess up by launching coroutines in another scope like `GlobalScope`, they will register as children of `viewModelScope` and get cancelled recursively. – Marko Topolnik Apr 11 '19 at 07:35
  • Is it good practice to use delay in viewModel to give some pause? If not, what we can use? – Anshul Tyagi May 05 '23 at 05:32