Search code examples
androidandroid-architecture-componentsandroid-livedataandroid-viewmodelkotlin-coroutines

Should I pass viewModelScope.coroutineContext to liveData builder function?


viewModelScope is used to bind a coroutine lifetime to the ViewModel lifecycle. liveData builder creates a LiveData that runs a coroutine, which lifetime is bound to the LiveData state, so, when the LiveData isn't active, the coroutine cancels after a timeout. Because of the timeout, the coroutine won't be cancelled on configuration change.

If I create a LiveData via liveData builder inside a ViewModel, and observe that LiveData in the Activity, LiveData lifecycle is already bound to the Activity lifecycle. Should I additionally pass the viewModelScope.coroutineContext to the liveData builder? I think that I shouldn't, but in one of the Android documentation samples it passes:

class MyViewModel: ViewModel() {
    private val userId: LiveData<String> = MutableLiveData()
    val user = userId.switchMap { id ->
        liveData(context = viewModelScope.coroutineContext + Dispatchers.IO) {
            emit(database.loadUserById(id))
        }
    }
}

Solution

  • Q: LiveData lifecycle is already bound to the Activity lifecycle. Should I pass the viewModelScope to the liveData builder?

    In simple cases, when an Activity has just one ViewModel, the Activity lifecycle is the same as the ViewModel lifecycle, and it shouldn't change anything, whether you pass 'viewModelScope' to the lifeData builder or not. But in more complex cases, for example, when the ViewModel is shared between fragments, the Fragment lifecycle may not match the shared ViewModel lifecyle, in such cases starting of the coroutine within 'viewModelScope.coroutineContext' makes sense.


    So, you can use viewModelScope to provide context to your liveData builder.

    Why?

    According to official doc: A ViewModelScope is defined for each ViewModel in your app. Any coroutine launched in this scope is automatically canceled if the ViewModel is cleared.

    So, it helps cancelling current job in your LiveData because, it's now bounded to your ViewModelScope.

    Additionally, viewModelScope is helpful if you are computing some data for a layout, you should scope the work to the ViewModel so that if the ViewModel is cleared, the work is canceled automatically to avoid consuming resources.