Android Work Manager -  Chain Request

Android Work Manager - Chain Request

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 return Result and here we are interested in Result.success().
  • This Result.success() will takeData` 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 to Result.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 WorkManagerusing thebeginWith()`

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