InputMerger and ArrayCreatingInputMerger with WorkManager

In the last article, we discussed how we can set input and output data with WorkManager API. (If you haven’t read the previous article I highly recommended you to read before proceeding.) 

In this article, we’re going to learn how we can convert multiple output results into one input using InputMerger.

I also wrote a pretty good article on how to simply work with WorkManager go and check it out.

Why do we need InputMerger…?

First, let’s see an example in which case we need the InputMerger. Let’s take the example from our previous article where two task are executed parallel and the result of these two tasks will fall into the third one.

WorkManager.getInstance()
        .beginWith(firstWorker, secondWorker)
        .then(thirdWorker)
        .enqueue()

The first and second task is performed in parallel, then the third one executed.

Let’s say the first task return such data.

val output = Data.Builder()
       .putString("keyA", "value1")
       .putInt("keyB", 1)
       .putString("keyC", "valueC")
       .build();
setOutputData(output);

And the second – such

val outputData = Data.Builder()
       .putString("keyA", "value2")
       .putInt("keyB", 2)
       .putString("keyD", "valueD")
       .build();
setOutputData(output);

Now we have the same keys, keyA and keyB are the same keys for both tasks. The case here to study which of these keys values will fall into third one – from the first task or from the second task.

Below is the result of these two workers.


Result of Worker3 ->  {keyA = value1, keyB = 1, keyC = valueC, keyD = valueD}

At first, I decided that it happened because of the first task is performed little longer than the second one, and it is logical that its values just overwrote the values from the second task when the keys match.

But then I started this sequence again and got this result.

Result of worker3 -> {keyA = value2, keyB = 2, keyC = valueC, keyD = valueD}

Now we see the values of the second task in the keys keyA and keyB. So, if the tasks are executed in parallel, then if the keys match, it is not known from which task you get the value.

Now, If the keys match, then only one value remains, what if we need all the data instead of overwriting. Here comes the concept of InputMerger with ArrayCreatingInputMerger.

Creating InputMerger With ArrayCreatingInputMerger

To convert multiple output results into one input, use InputMerger. There are several implementations of it, the default is OverwritingInputMerger. Now ArrayCreatingInputMerger creates an array in which all the values of this key are placed.

For verification, we use the same example.

val thirdWorker = OneTimeWorkRequest.Builder(ThirdWorker::class.java)
                          .setInputMerger(ArrayCreatingInputMerger::class.java)
                          .build()  
WorkManager.getInstance()
        .beginWith(firstWorker, secondWorker)
        .then(thirdWorker)
        .enqueue()

Now, when you merge the output data from the previous tasks into the input data of the third worker, ArrayCreatingInputMerger will be used.

The first task will return data like below.

val output = Data.Builder()
       .putString("keyA", "value1")
       .putInt("keyB", 1)
       .putString("keyC", "valueC")
       .build();
setOutputData(output);
Below is the second task returned data.
val outputData = Data.Builder()
       .putString("keyA", "value2")
       .putInt("keyB", 2)
       .putString("keyD", "valueD")
       .build();
setOutputData(output);

In the third task, we get the input data like this.

valueA = [value1, value2] 
valueB = [1, 2] 
valueC = [valueC] 
valueD = [valueD]

With ArrayCreatingInputMerger case, if the keys match, the data is not overwritten but is added to an Array.

Well before ending this blog I want to describe one more case. Let’s say if we have two task running parallel then third and fourth.

val thirdWorker = OneTimeWorkRequest.Builder(ThirdWorker::class.java) 
                        .setInputMerger(ArrayCreatingInputMerger::class.java) 
                        .build() 
val fourthWorker = OneTimeWorkRequest.Builder(ThirdWorker::class.java) 
                        .setInputMerger(ArrayCreatingInputMerger::class.java) 
                        .build()
WorkManager.getInstance()
         .beginWith(firstWorker,secondWorker)
         .then(thirdWorker,fourthWorker)
         .enqueue()

In this case, the input data obtained from the first and second tasks will also arrive in the third and fourth task both, with ArrayCreatingInputMerger will be used.

Alright, this is my demonstration about how do we set InputMerger with ArrayCreatingInputMerger. I hope you guys have learned something from this article. If you any queries according to this article or any other problem regarding WorkManager, please do comment below.

Thank you for being here and keep reading…

1 COMMENT

LEAVE A REPLY

Please enter your comment!
Please enter your name here