Search code examples
androidkotlinkotlin-android-extensionskotlin-extensionkotlin-coroutines

Cancel all Kotlin coroutines pending jobs on ViewModel's onCleared()


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()
}

Solution

  • 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)
        }
    }