Skip to content

ViewModelScope vs LifeCycleScope

  • by
ViewModel Scope vs LifeCycleScope

1. Overview

In this article, we will learn the differences between ViewModelScope vs LifeCycleScope.

Kotlin coroutines provide an API that enables you to write asynchronous code. With Kotlin coroutines, you can define a CoroutineScope, which helps you to manage when your coroutines should run. Each asynchronous operation runs within a particular scope.

Lifecycle-aware components provide first-class support for coroutines for logical scopes in your app, along with an interoperability layer with LiveData.

2. Android ViewModelScope

A ViewModelScope is defined for each ViewModel in your app. You can access the CoroutineScope of a ViewModel through the viewModelScope property of the ViewModel. Thus, you can use this scope directly in your ViewModel for launching coroutines instead of creating a new coroutine scope. This ViewModelScope is tied to the ViewModel.

You must add the following dependency in your project:

androidx.lifecycle:lifecycle-viewmodel-ktx:2.4.0

Any coroutine launched in this scope is automatically canceled if the ViewModel is cleared. You can use this scope when you want the task to execute only if the ViewModel is active.

Basically, in the MVVM pattern we use ViewModel manages the data and tied to a particular Activity/Fragment. So once that Activity/Fragment gets destroyed, its corresponding ViewModel also cleared. Thus, it cancels all incomplete jobs started by the viewModelScope, throwing CancellationException.

Look at the following code. The getHeadlines method uses the viewModelScope to launch the coroutine that would execute a suspend function headlinesDataSource.getAllUSHeadlines(map). The viewModelScope is available for use automatically in your view model.

@HiltViewModel
open class HeadlinesViewModel @Inject constructor(private val headlinesDataSource: HeadlinesDataSource): ViewModel() {

    private val _res = MutableLiveData<Resource<HeadlinesResponse>>()

    val res : LiveData<Resource<HeadlinesResponse>>
        get() = _res

    init {
        getHeadlines()
    }

    fun getHeadlines()  = viewModelScope.launch {

        _res.postValue(Resource.loading(null))

        val map = HashMap<String, String>()
        map["country"] = AppConstants.COUNTRY
        map["category"] = AppConstants.BUSINESS
        map["apiKey"] = BuildConfig.API_KEY

        headlinesDataSource.getAllUSHeadlines(map).let { resp ->
            _res.postValue(Resource.success(resp))
        }

    }
}

Assume the suspend function is still in execution. Now, user presses the back button causing the activity or fragment to destroy. Once it is destroyed, the view model is also cleared. Android then would also cancel the coroutines executing within the view model scope.

3. LifeCycleScope

LifecycleScope is defined for each Lifecycle object. A Lifecycle is a class that holds the information about the lifecycle state of a component (like an activity or a fragment) and allows other objects to observe this state. 

Android cancels any coroutine launched in this scope when the corresponding Lifecycle is destroyed. You can access the CoroutineScope of the Lifecycle either via lifecycle.coroutineScope or lifecycleOwner.lifecycleScope properties. A lifecycle owner is a class that has an Android lifecycle. 

For example, the fragment itself is the LifecycleOwner. The below fragment uses the lifecycleOwner.lifecycleScope to create precomputed text asynchronously:

class MyFragment: Fragment() {
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        viewLifecycleOwner.lifecycleScope.launch {
            val params = TextViewCompat.getTextMetricsParams(textView)
            val precomputedText = withContext(Dispatchers.Default) {
                PrecomputedTextCompat.create(longTextContent, params)
            }
            TextViewCompat.setPrecomputedText(textView, precomputedText)
        }
    }
}

4. Conclusion

To sum up, we have learned the differences between ViewModelScope vs LifeCycleScope.

Leave a Reply

Your email address will not be published. Required fields are marked *