Coroutine scopes in Kotlin

There are libraries that actually help us do structured concurrency without having to write boilerplate in every ViewModel. In order to use these libraries, we need to know the types of coroutine scopes that exist.

ViewModel scope

Coroutines in this scope are useful when there is work that should only be done when a ViewModel is active. To avoid boilerplate, add the code below to your build.gradle file.

implementation “androidx.lifecycle:lifecycle-viewmodel-ktx:$view_model_scope_version”

This library adds viewModelScope as an extension function and binds the scope to Dispatchers.Main by default. However, the dispatcher can be changed if need be. The job is also automatically canceled when the ViewModel is cleared, so all we have to do is this:

class MainViewModel : ViewModel(){
private fun doSomething(){
viewModelScope.launch(Dispatchers.Default){ //Specify dispatcher if you like
// Coroutine is launched. Time to do something.
}
}
// No need to override onCleared, it's taken care of :)
}

Lifecycle scope

A LifecycleScope is defined for each Lifecycle object. LifecycleOwner could be an Activity or a Fragment. Any coroutine lanced in this scope is canceled when the Lifecycle is destroyed. You can access the Lifecycle’s CoroutineScope via lifecycle.coroutineScope or lifecycleOwner.lifecycleScope properties. To use this, add the following dependency to your build.gradle file.

implementation “androidx.lifecycle:lifecycle-runtime-ktx:$lifecycle_scope_version”

Launching a coroutine using this scope can be done like this:

class HomeFragment: Fragment() {
...
private fun doSomething(){
lifecycleOwner.lifecycleScope.launch {
// Coroutine launched. Do some computation here.
}
}
}

This is a lot cleaner than writing boilerplate when you want to launch a coroutine.