Search code examples
androidandroid-workmanager

Android WorkManager fork single into multiple chains and join


I want to set up the following work using WorkManager:

   A
   |
   v
 -----
|     |
v     |
B     v
|     D
v     |
C     |
|     |
 -----
   |
   v
   E

So first, A should should run, then B followed by C while D runs in parallel. After that, E should run.

Joining the two parallel chains before running E can be done with WorkContinuation.combine(). My problem is that I cannot figure out how to do the forking into two parallel chains after A. (It would be simple if the left chain containing B and C wasn't an actual chain of two requests but only a single request.)


Solution

  • As you wrote, the chain you want to build is not possible to implement with WorkManager. You can open a feature request on WorkManager's issuetracker.

    Going back to your chain, I wonder if it can be modified to fit into WorkManager API:

       A
       |
       v
     -----
    |     |
    v     |
    B     v
    |     D
    |     |
     -----
       |
       v
       C
       |
       v
       E
    

    In this case you need to handle with some logic the input merger into C so that it does what you expect, this if you have data passed between the Worker classes. But you maintain the same constraints (but in this case C requires that you terminate D before it is started).

    In this case, following WorkManager's documentation, you can have something like:

            val workRequestA = OneTimeWorkRequestBuilder<SaveImageToFileWorker>().build()
            val workRequestB = OneTimeWorkRequestBuilder<SaveImageToFileWorker>().build()
            val workRequestC = OneTimeWorkRequestBuilder<SaveImageToFileWorker>()
                    .setInputMerger(ArrayCreatingInputMerger::class.java)
                    .build()
            val workRequestD = OneTimeWorkRequestBuilder<SaveImageToFileWorker>().build()
            val workRequestE = OneTimeWorkRequestBuilder<SaveImageToFileWorker>().build()
    
            var continution = workManager
                    .beginWith(workRequestA)
                    .then(listOf(workRequestB, workRequestD))
                    .then(workRequestC)
                    .then(workRequestE)
                    .enqueue()