[Kotlin coroutines](https://developer.android.com/kotlin/coroutines)provide an API that enables you to write asynchronous code. With Kotlin coroutines, you can define a[`CoroutineScope`](https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-coroutine-scope/), which helps you to manage when your coroutines should run. Each asynchronous operation runs within a particular scope.

[Lifecycle-aware components](https://developer.android.com/topic/libraries/architecture/lifecycle)provide first-class support for coroutines for logical scopes in your app along with an interoperability layer with[`LiveData`](https://developer.android.com/topic/libraries/architecture/livedata). This topic explains how to use coroutines effectively with lifecycle-aware components.

## Add KTX dependencies

The built-in coroutine scopes described in this topic are contained in the[KTX extensions](https://developer.android.com/kotlin/ktx)for each corresponding component. Be sure to add the appropriate dependencies when using these scopes.

- For[`ViewModelScope`](https://developer.android.com/topic/libraries/architecture/coroutines#viewmodelscope), use`androidx.lifecycle:lifecycle-viewmodel-ktx:2.4.0`or higher.
- For[`LifecycleScope`](https://developer.android.com/topic/libraries/architecture/coroutines#lifecyclescope), use`androidx.lifecycle:lifecycle-runtime-ktx:2.4.0`or higher.
- For[`liveData`](https://developer.android.com/topic/libraries/architecture/coroutines#livedata), use`androidx.lifecycle:lifecycle-livedata-ktx:2.4.0`or higher.

## Lifecycle-aware coroutine scopes

Lifecycle-aware components define the following built-in scopes that you can use in your app.

### ViewModelScope

A`ViewModelScope`is defined for each[`ViewModel`](https://developer.android.com/topic/libraries/architecture/viewmodel)in your app. Any coroutine launched in this scope is automatically canceled if the`ViewModel`is cleared. Coroutines are useful here for when you have work that needs to be done only if the`ViewModel`is active. For example, 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.

You can access the`CoroutineScope`of a`ViewModel`through the`viewModelScope`property of the ViewModel, as shown in the following example:  

    class MyViewModel: ViewModel() {
        init {
            viewModelScope.launch {
                // Coroutine that will be canceled when the ViewModel is cleared.
            }
        }
    }

### LifecycleScope

A`LifecycleScope`is defined for each[`Lifecycle`](https://developer.android.com/topic/libraries/architecture/lifecycle)object. Any coroutine launched in this scope is canceled when the`Lifecycle`is destroyed. You can access the`CoroutineScope`of the`Lifecycle`either via`lifecycle.coroutineScope`or`lifecycleOwner.lifecycleScope`properties.

The example below demonstrates how to use`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)
            }
        }
    }

## Restartable Lifecycle-aware coroutines

Even though the`lifecycleScope`provides a proper way to cancel long-running operations automatically when the`Lifecycle`is`DESTROYED`, you might have other cases where you want to start the execution of a code block when the`Lifecycle`is in a certain state, and cancel when it is in another state. For example, you might want to collect a flow when the`Lifecycle`is`STARTED`and cancel the collection when it's`STOPPED`. This approach processes the flow emissions only when the UI is visible on the screen, saving resources and potentially avoiding app crashes.

For these cases,`Lifecycle`and`LifecycleOwner`provide the suspend`repeatOnLifecycle`API that does exactly that. The following example contains a code block that runs every time the associated`Lifecycle`is at least in the`STARTED`state and cancels when the`Lifecycle`is`STOPPED`:  

    class MyFragment : Fragment() {

        val viewModel: MyViewModel by viewModel()

        override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
            super.onViewCreated(view, savedInstanceState)

            // Create a new coroutine in the lifecycleScope
            viewLifecycleOwner.lifecycleScope.launch {
                // repeatOnLifecycle launches the block in a new coroutine every time the
                // lifecycle is in the STARTED state (or above) and cancels it when it's STOPPED.
                viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
                    // Trigger the flow and start listening for values.
                    // This happens when lifecycle is STARTED and stops
                    // collecting when the lifecycle is STOPPED
                    viewModel.someDataFlow.collect {
                        // Process item
                    }
                }
            }
        }
    }

### Lifecycle-aware flow collection

If you only need to perform lifecycle-aware collection on a single flow, you can use the[`Flow.flowWithLifecycle()`](https://developer.android.com/reference/kotlin/androidx/lifecycle/package-summary#flowwithlifecycle)method to simplify your code:  

    viewLifecycleOwner.lifecycleScope.launch {
        exampleProvider.exampleFlow()
            .flowWithLifecycle(viewLifecycleOwner.lifecycle, Lifecycle.State.STARTED)
            .collect {
                // Process the value.
            }
    }

However, if you need to perform lifecycle-aware collection on multiple flows in parallel, then you must collect each flow in different coroutines. In that case, it's more efficient to use`repeatOnLifecycle()`directly:  

    viewLifecycleOwner.lifecycleScope.launch {
        viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
            // Because collect is a suspend function, if you want to
            // collect multiple flows in parallel, you need to do so in
            // different coroutines.
            launch {
                flow1.collect { /* Process the value. */ }
            }

            launch {
                flow2.collect { /* Process the value. */ }
            }
        }
    }

## Suspend Lifecycle-aware coroutines

Even though the`CoroutineScope`provides a proper way to cancel long-running operations automatically, you might have other cases where you want to suspend execution of a code block unless the`Lifecycle`is in a certain state. For example, to run a`FragmentTransaction`, you must wait until the`Lifecycle`is at least`STARTED`. For these cases,`Lifecycle`provides additional methods:`lifecycle.whenCreated`,`lifecycle.whenStarted`, and`lifecycle.whenResumed`. Any coroutine run inside these blocks is suspended if the`Lifecycle`isn't at least in the minimal desired state.

The example below contains a code block that runs only when the associated`Lifecycle`is at least in the`STARTED`state:  

    class MyFragment: Fragment {
        init { // Notice that we can safely launch in the constructor of the Fragment.
            lifecycleScope.launch {
                whenStarted {
                    // The block inside will run only when Lifecycle is at least STARTED.
                    // It will start executing when fragment is started and
                    // can call other suspend methods.
                    loadingView.visibility = View.VISIBLE
                    val canAccess = withContext(Dispatchers.IO) {
                        checkUserAccess()
                    }

                    // When checkUserAccess returns, the next line is automatically
                    // suspended if the Lifecycle is not *at least* STARTED.
                    // We could safely run fragment transactions because we know the
                    // code won't run unless the lifecycle is at least STARTED.
                    loadingView.visibility = View.GONE
                    if (canAccess == false) {
                        findNavController().popBackStack()
                    } else {
                        showContent()
                    }
                }

                // This line runs only after the whenStarted block above has completed.

            }
        }
    }

If the`Lifecycle`is destroyed while a coroutine is active via one of the`when`methods, the coroutine is automatically canceled. In the example below, the`finally`block runs once the`Lifecycle`state is`DESTROYED`:  

    class MyFragment: Fragment {
        init {
            lifecycleScope.launchWhenStarted {
                try {
                    // Call some suspend functions.
                } finally {
                    // This line might execute after Lifecycle is DESTROYED.
                    if (lifecycle.state >= STARTED) {
                        // Here, since we've checked, it is safe to run any
                        // Fragment transactions.
                    }
                }
            }
        }
    }

| **Note:** Even though these methods provide convenience when working with`Lifecycle`, you should use them only when the information is valid within the scope of the`Lifecycle`(precomputed text, for example). Keep in mind that if the activity restarts, the coroutine is not restarted.
| **Warning:** Prefer collecting flows using the`repeatOnLifecycle`API instead of collecting inside the`launchWhenX`APIs. As the latter APIs suspend the coroutine instead of cancelling it when the`Lifecycle`is`STOPPED`, upstream flows are kept active in the background, potentially emitting new items and wasting resources.

## Use coroutines with LiveData

When using[`LiveData`](https://developer.android.com/topic/libraries/architecture/livedata), you might need to calculate values asynchronously. For example, you might want to retrieve a user's preferences and serve them to your UI. In these cases, you can use the`liveData`builder function to call a`suspend`function, serving the result as a`LiveData`object.

In the example below,`loadUser()`is a suspend function declared elsewhere. Use the`liveData`builder function to call`loadUser()`asynchronously, and then use`emit()`to emit the result:  

    val user: LiveData<User> = liveData {
        val data = database.loadUser() // loadUser is a suspend function.
        emit(data)
    }

The`liveData`building block serves as a[structured concurrency primitive](https://medium.com/@elizarov/structured-concurrency-722d765aa952)between coroutines and`LiveData`. The code block starts executing when`LiveData`becomes active and is automatically canceled after a configurable timeout when the`LiveData`becomes inactive. If it is canceled before completion, it is restarted if the`LiveData`becomes active again. If it completed successfully in a previous run, it doesn't restart. Note that it is restarted only if canceled automatically. If the block is canceled for any other reason (e.g. throwing a`CancellationException`), it is**not**restarted.

You can also emit multiple values from the block. Each`emit()`call suspends the execution of the block until the`LiveData`value is set on the main thread.  

    val user: LiveData<Result> = liveData {
        emit(Result.loading())
        try {
            emit(Result.success(fetchUser()))
        } catch(ioException: Exception) {
            emit(Result.error(ioException))
        }
    }

You can also combine`liveData`with[`Transformations`](https://developer.android.com/reference/androidx/lifecycle/Transformations), as shown in the following example:  

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

You can emit multiple values from a`LiveData`by calling the`emitSource()`function whenever you want to emit a new value. Note that each call to`emit()`or`emitSource()`removes the previously-added source.  

    class UserDao: Dao {
        @Query("SELECT * FROM User WHERE id = :id")
        fun getUser(id: String): LiveData<User>
    }

    class MyRepository {
        fun getUser(id: String) = liveData<User> {
            val disposable = emitSource(
                userDao.getUser(id).map {
                    Result.loading(it)
                }
            )
            try {
                val user = webservice.fetchUser(id)
                // Stop the previous emission to avoid dispatching the updated user
                // as `loading`.
                disposable.dispose()
                // Update the database.
                userDao.insert(user)
                // Re-establish the emission with success type.
                emitSource(
                    userDao.getUser(id).map {
                        Result.success(it)
                    }
                )
            } catch(exception: IOException) {
                // Any call to `emit` disposes the previous one automatically so we don't
                // need to dispose it here as we didn't get an updated value.
                emitSource(
                    userDao.getUser(id).map {
                        Result.error(exception, it)
                    }
                )
            }
        }
    }

For more coroutines-related information, see the following links:

- [Improve app performance with Kotlin coroutines](https://developer.android.com/kotlin/coroutines)
- [Coroutines overview](https://kotlinlang.org/docs/reference/coroutines-overview.html)
- [Threading in CoroutineWorker](https://developer.android.com/topic/libraries/architecture/workmanager/advanced/coroutineworker)

## Additional resources

To learn more about using coroutines with lifecycle-aware components, consult the following additional resources.

### Samples

### Blogs

- [Coroutines on Android: Application patterns](https://medium.com/androiddevelopers/coroutines-on-android-part-iii-real-work-2ba8a2ec2f45)
- [Easy coroutines in Android: viewModelScope](https://medium.com/androiddevelopers/easy-coroutines-in-android-viewmodelscope-25bffb605471)
- [Testing two consecutive LiveData emissions in coroutines](https://medium.com/androiddevelopers/testing-two-consecutive-livedata-emissions-in-coroutines-5680b693cbf8)

## Recommended for you

- Note: link text is displayed when JavaScript is off
- [LiveData overview](https://developer.android.com/topic/libraries/architecture/livedata)
- [Handling Lifecycles with Lifecycle-Aware Components](https://developer.android.com/topic/libraries/architecture/lifecycle)
- [Load and display paged data](https://developer.android.com/topic/libraries/architecture/paging/v3-paged-data)