正文
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.
Recommended for you
-
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
.