WorkManager allows you to create and enqueue a chain of work that specifies multiple dependent tasks and defines what order they should run in. This functionality is particularly useful when you need to run several tasks in a particular order.

To create a chain of work, you can use[`WorkManager.beginWith(OneTimeWorkRequest)`](https://developer.android.com/reference/androidx/work/WorkManager#beginWith(androidx.work.OneTimeWorkRequest))or[`WorkManager.beginWith(List<OneTimeWorkRequest>)`](https://developer.android.com/reference/androidx/work/WorkManager#beginWith(java.util.List%3Candroidx.work.OneTimeWorkRequest%3E)), which each return an instance of[`WorkContinuation`](https://developer.android.com/reference/androidx/work/WorkContinuation).

A`WorkContinuation`can then be used to add dependent`OneTimeWorkRequest`instances using[`then(OneTimeWorkRequest)`](https://developer.android.com/reference/androidx/work/WorkContinuation#then(androidx.work.OneTimeWorkRequest))or[`then(List<OneTimeWorkRequest>)`](https://developer.android.com/reference/androidx/work/WorkContinuation#then(java.util.List%3Candroidx.work.OneTimeWorkRequest%3E)).

Every invocation of the`WorkContinuation.then(...)`returns a*new* instance of`WorkContinuation`. If you add a`List`of`OneTimeWorkRequest`instances, these requests can potentially run in parallel.

Finally, you can use the[`WorkContinuation.enqueue()`](https://developer.android.com/reference/androidx/work/WorkContinuation#enqueue())method to`enqueue()`your chain of`WorkContinuation`s.

Let's look at an example. In this example, 3 different Worker jobs are configured to run (potentially in parallel). The results of these Workers are then joined and passed on to a caching Worker job. Finally, the output of that job is passed into an upload Worker, which uploads the results to a remote server.  

### Kotlin

```kotlin
WorkManager.getInstance(myContext)
   // Candidates to run in parallel
   .beginWith(listOf(plantName1, plantName2, plantName3))
   // Dependent work (only runs after all previous work in chain)
   .then(cache)
   .then(upload)
   // Call enqueue to kick things off
   .enqueue()
```

### Java

```java
WorkManager.getInstance(myContext)
   // Candidates to run in parallel
   .beginWith(Arrays.asList(plantName1, plantName2, plantName3))
   // Dependent work (only runs after all previous work in chain)
   .then(cache)
   .then(upload)
   // Call enqueue to kick things off
   .enqueue();
```

## Input Mergers

When you chain`OneTimeWorkRequest`instances, the output of parent work requests is passed in as input to the children. So in the above example, the outputs of`plantName1`,`plantName2`, and`plantName3`would be passed in as inputs to the`cache`request.

In order to manage inputs from multiple parent work requests, WorkManager uses[`InputMerger`](https://developer.android.com/reference/androidx/work/InputMerger).

There are two different types of`InputMerger`provided by WorkManager:

- [`OverwritingInputMerger`](https://developer.android.com/reference/androidx/work/OverwritingInputMerger)attempts to add all keys from all inputs to the output. In case of conflicts, it overwrites the previously-set keys.

- [`ArrayCreatingInputMerger`](https://developer.android.com/reference/androidx/work/ArrayCreatingInputMerger)attempts to merge the inputs, creating arrays when necessary.

If you have a more specific use case, then you can write your own by subclassing`InputMerger`.

### OverwritingInputMerger

`OverwritingInputMerger`is the default merger method. If there are key conflicts in the merger, then the latest value for a key will overwrite any previous versions in the resulting output data.

For example, if the plant inputs each have a key matching their respective variable names (`"plantName1"`,`"plantName2"`, and`"plantName3"`), then the data passed to the`cache`worker will have three key-value pairs.

![Diagram showing three jobs passing different outputs to the next job in the chain. Since the three outputs all have different keys, the next job receives three key/value pairs.](https://developer.android.com/static/images/topic/libraries/architecture/workmanager/how-to/chaining-overwriting-merger-example.png)

If there is a conflict, then the last worker to complete "wins", and its value is passed to`cache`.

![Diagram showing three jobs passing outputs to the next job in the chain. In this case, two of those jobs produce outputs with the same key. As a result, the next job receives two key/value pairs, with one of the conflicting outputs dropped.](https://developer.android.com/static/images/topic/libraries/architecture/workmanager/how-to/chaining-overwriting-merger-conflict.png)

Because your work requests are run in parallel, you do not have guarantees for the order in which it runs. In the example above,`plantName1`could hold a value of either`"tulip"`or`"elm"`, depending on which value is written last. If you have a chance of a key conflict and you need to preserve all output data in a merger, then`ArrayCreatingInputMerger`may be a better option.

### ArrayCreatingInputMerger

For the above example, given that we want to preserve the outputs from all plant name Workers, we should use an`ArrayCreatingInputMerger`.  

### Kotlin

```kotlin
val cache: OneTimeWorkRequest = OneTimeWorkRequestBuilder<PlantWorker>()
   .setInputMerger(ArrayCreatingInputMerger::class)
   .setConstraints(constraints)
   .build()
```

### Java

```java
OneTimeWorkRequest cache = new OneTimeWorkRequest.Builder(PlantWorker.class)
       .setInputMerger(ArrayCreatingInputMerger.class)
       .setConstraints(constraints)
       .build();
```

`ArrayCreatingInputMerger`pairs each key with an array. If each of the keys is unique, then your result is a series of one-element arrays.

![Diagram showing three jobs passing different outputs to the next job in the chain. The next job is passed three arrays, one for each of the output keys. Each array has a single member.](https://developer.android.com/static/images/topic/libraries/architecture/workmanager/how-to/chaining-array-merger-example.png)

If there are any key collisions, then any corresponding values are grouped together in an array.

![Diagram showing three jobs passing outputs to the next job in the chain. In this case, two of those jobs produce outputs with the same key. The next job is passed two arrays, one for each key. One of those arrays has two members, since there were two outputs with that key.](https://developer.android.com/static/images/topic/libraries/architecture/workmanager/how-to/chaining-array-merger-conflict.png)

## Chaining and Work Statuses

Chains of`OneTimeWorkRequest`execute sequentially as long as their work completes successfully (that is, they return a`Result.success()`). Work requests may fail or be cancelled while running, which has downstream effects on dependent work requests.

When the first`OneTimeWorkRequest`is enqueued in a chain of work requests, all subsequent work requests are blocked until the work of that first work request is completed.

![Diagram showing a chain of jobs. The first job is enqueued; all successive jobs are blocked until the first one finishes.](https://developer.android.com/static/images/topic/libraries/architecture/workmanager/how-to/chaining-enqueued-all-blocked.png)

Once enqueued and all work constraints are satisfied, the first work request begins running. If work is successfully completed in the root`OneTimeWorkRequest`or`List<OneTimeWorkRequest>`(that is, it returns a`Result.success()`), then the next set of dependent work requests will be enqueued.

![Diagram showing a chain of jobs. The first job has succeeded, and its two immediate successors are enqueued. The remaining jobs are blocked their preceding jobs finish.](https://developer.android.com/static/images/topic/libraries/architecture/workmanager/how-to/chaining-enqueued-in-progress.png)

As long as each work request completes successfully, this same pattern propagates through the rest of your chain of work requests until all work in the chain is completed. While that is the simplest and often preferred case, error states are just as important to handle.

When an error occurs while a worker is processing your work request then you can retry that request according to a[backoff policy you define](https://developer.android.com/topic/libraries/architecture/workmanager/how-to/define-work#retries_backoff). Retrying a request that is a part of a chain means that just that request will be retried with the input data provided to it. Any work running in parallel will be unaffected.

![Diagram showing a chain of jobs. One of the jobs failed, but had a backoff policy defined. That job will rerun after the appropriate amount of time has passed. The jobs after it in the chain are blocked until it runs successfully.](https://developer.android.com/static/images/topic/libraries/architecture/workmanager/how-to/chaining-enqueued-retry.png)

For more information on defining custom retry strategies, see[Retry and Backoff Policy](https://developer.android.com/topic/libraries/architecture/workmanager/how-to/define-work#retries_backoff).

If that retry policy is undefined or exhausted, or you otherwise reach some state in which a`OneTimeWorkRequest`returns`Result.failure()`, then that work request and all dependent work requests are marked as`FAILED.`

![Diagram showing a chain of jobs. One job has failed and cannot be retried. As a result, all jobs after it in the chain also fail.](https://developer.android.com/static/images/topic/libraries/architecture/workmanager/how-to/chaining-enqueued-failed.png)

The same logic applies when a`OneTimeWorkRequest`is cancelled. Any dependent work requests are also marked`CANCELLED`and their work will not be executed.

![Diagram showing a chain of jobs. One job has been cancelled. As a result, all jobs after it in the chain are also cancelled.](https://developer.android.com/static/images/topic/libraries/architecture/workmanager/how-to/chaining-enqueued-cancelled.png)

Note that if you were to append more work requests to a chain that has failed or has cancelled work requests, then your newly appended work request will also be marked`FAILED`or`CANCELLED`, respectively. If you want to extend the work of an existing chain, see`APPEND_OR_REPLACE`in[ExistingWorkPolicy](https://developer.android.com/reference/androidx/work/ExistingWorkPolicy).

When creating chains of work requests, dependent work requests should define retry policies to ensure that work is always completed in a timely manner. Failed work requests could result in incomplete chains and/or unexpected state.

For more information, see[Cancelling and Stopping Work](https://developer.android.com/topic/libraries/architecture/workmanager/how-to/cancel-stop-work).