This blog article discusses about work manager with chain requests
First we will understand how to make worker's output available to next one
Result
As we have seen in early article ( Android Work Manager Basics ) ,
doWork
method will returnResult
and here we are interested inResult.success()
.- This
Result.success() will take
Data` as parameter
Data
- A set of key/value pairs used as input and output for workers
- Keys are always string
- Values can be String , Primitive Data types and their array variants
- This is a light weight container which can take upto 10kb of data
- This will throw
IllegalStateException
if it crosses the 10kb of data.
For Ex: Worker 2 will take output of Worker 1 to complete the work assigned.
Adding Data
to Result
- As we have already seen
Data
needs to be passed toResult.success()
for next worker. - This can be done by using the method
workDataOf()
workDataOf()
- converts the list of pair object to
Data
object as below
// key
const val TOTAL_COUNT = "total_count"
// value
val total = 100
val output = workDataOf(TOTAL_COUNT to total)
Result.success(output)
We will learn the work manger chain tequest by 2 workers
- Worker 1 - making the work manager to sumup the numbers from 1 to 10 with 2 secs delay for each addition
- Worker 2 - take the output of worker 1 (sum of 1 to 10) and multiply with 1256 with a delay of 3 secs.
The basic work manager setup can be found at ( Android Work Manager Basics )
Adding Worker's output to Result.success()
// return is result based on the total
return if (total > 0) {
Log.d("SimpleAddWorker", "Success and total is $total")
val totalAddData = workDataOf(OUTPUT_TOTAL_ADD_WORKER to total)
Result.success(totalAddData)
} else {
Log.d("SimpleAddWorker", "Failure and total is $total")
Result.failure()
}
In the above code , as already discussed we have created Data
object by using
workDataOf() method.
val totalAddData = workDataOf(OUTPUT_TOTAL_ADD_WORKER to total)
and then add the Data
object to Result.suucess()
Result.success(totalAddData)
Create a multiply worker
Log.d("SimpleAddWorker", "Thread : Multiply -> ${Thread.currentThread().name}")
// get the total from Add worker
val addTotal = inputData.getInt(OUTPUT_TOTAL_ADD_WORKER, 0)
// put thread to sleep for 3 secs
sleepForMultiplication()
val multiTotal = addTotal * 1256;
return if (multiTotal > 0) {
val grandTotal = workDataOf(OUTPUT_MULTI_WORKER to multiTotal)
Log.d("SimpleAddWorker", "Grand Total : $multiTotal.")
Result.success(grandTotal)
} else {
Result.failure()
}
In the above code
- get the output of worker1 using
inputData
to respective data type - use the worker 1 output for calculation
- based on total we can return respective
Result
Chaining the Work Request
// call the work manager to begin the task by using the OneTimeWorkRequest
val addWorker = OneTimeWorkRequestBuilder<SimpleAddWorker>().build()
val multiWorker = OneTimeWorkRequestBuilder<MultiplyWorker>().build()
workManager.beginWith(addWorker)
.then(multiWorker)
.enqueue()
In the above code ,
- create a individual work request for each worker
- pass the first work request you want to WorkManager
using the
beginWith()`
beginWith() - begins a chain of one or more work request which can be enqueue together
- pass the second work request using the
then()
then() - Adds a new work request based on the successful completion of previous work request
- As simply put , next we can enqueue the work request using WorkContinuation
Output :
D/SimpleAddWorker: Thread : main
D/SimpleAddWorker: Thread : Add -> pool-1-thread-1
D/SimpleAddWorker: adding : 1 by adding 1
D/SimpleAddWorker: adding : 3 by adding 2
D/SimpleAddWorker: adding : 6 by adding 3
D/SimpleAddWorker: adding : 10 by adding 4
D/SimpleAddWorker: adding : 15 by adding 5
D/SimpleAddWorker: adding : 21 by adding 6
D/SimpleAddWorker: adding : 28 by adding 7
D/SimpleAddWorker: adding : 36 by adding 8
D/SimpleAddWorker: adding : 45 by adding 9
D/SimpleAddWorker: adding : 55 by adding 10
D/SimpleAddWorker: Success and total is 55
I/WM-WorkerWrapper: Worker result SUCCESS for Work [ id=69adb0c7-8759-4bad-87a3-4efa17fb30a0, tags={ com.vpdevs.chainworkrequestwm.workers.SimpleAddWorker } ]
D/SimpleAddWorker: Thread : Multiply -> pool-1-thread-2
D/SimpleAddWorker: Grand Total : 69080
The sample code for the above can be found at github.com/vprabhu/WorkManagerChainWorkRequ..
In the next article , we will discuss about the UI update using ViewModel
Please leave comments to improve
Enjoy coding