What is difference between MediatorLiveData and MutableLiveData in MVVM

34,935

Solution 1

At first we need to know what is the relation between MutableLivedata and MediatorLivedata to understand the difference between them.

java.lang.Object
  ↳ android.arch.lifecycle.LiveData<T>
      ↳ android.arch.lifecycle.MutableLiveData<T>
          ↳ android.arch.lifecycle.MediatorLiveData<T>

Now it is clear that MediatorLiveData is a subclass of MutableLiveData therefore MediatorLiveData can access each and every property of MutableLiveData as well as LiveData.

Question no. 1 is answered partially and rest of the answer will be discussed at the end of Question no. 2's answer.

After researching on some sample projects as well as android developer's official site I found that MutableLiveData should be used only for notifying your UI when observing any data.

For example, you want to display two SeekBars on two different fragments(Fragment1 and Fragment2) and you also want them to be synced when operating from Fragment1.

Another scenario is that we have 2 instances of LiveData, let's name them liveData1 and liveData2, and we want to merge their emissions in one object: liveDataMerger (which is a MediatorLiveData object). Then, liveData1 and liveData2 will become sources for the liveDataMerger and every time onChanged callback is called for either of them, we set a new value in liveDataMerger.

LiveData liveData1 = ...;
LiveData liveData2 = ...;

MediatorLiveData liveDataMerger = new MediatorLiveData<>();
liveDataMerger.addSource(liveData1, value ->liveDataMerger.setValue(value));
liveDataMerger.addSource(liveData2, value -> liveDataMerger.setValue(value));

In this case you cannot use MutableLiveData but on the other hand if you want to compare data into the first example (where MutableLiveData has been used) then you cannot because you will be unable to use the addSource property (as per class hierarchy).

Solution 2

MutableLiveData is a subclass of LiveData thats exposes the setValue and postValue methods (the second one is thread safe), so you can dispatch a value to any active observers.

MediatorLiveData can observe other LiveData objects (sources) and react to their onChange events, this will give you control on when you want to propagate the event, or do something in particular.

Take a look of the following google's example:

Let's consider that we only want 10 values emitted by liveData1, to be merged in the liveDataMerger. Then, after 10 values, we can stop listening to liveData1 and remove it as a source.

Java

liveDataMerger.addSource(liveData1, new Observer() {
      private int count = 1;

      @Override public void onChanged(@Nullable Integer s) {
          count++;
          liveDataMerger.setValue(s);
          if (count > 10) {
              liveDataMerger.removeSource(liveData1);
          }
      }
 });

Kotlin

liveDataMerger.addSource(liveData1, object : Observer<Int> {
    private var count = 1

    override fun onChanged(s: Int?) {
        count++
        liveDataMerger.value = s
        if (count > 10) {
            liveDataMerger.removeSource(liveData1)
        }
    }
})

Solution 3

MediatorLiveData<String> mediatorLiveData = new MediatorLiveData<String>();

public MutableLiveData<String> liveData1 = new  MutableLiveData<String>();
public MutableLiveData<String> liveData2 = new  MutableLiveData<String>();

mediatorLiveData.addSource(liveData1,
    new Observer<String>() {
        @Override
        public void onChanged(String s) {
            mediatorLiveData.setValue(s + " - emission from observer of liveData1");
        }
    }
);
mediatorLiveData.addSource(liveData2,
    new Observer<String>() {
        @Override
        public void onChanged(String s) {
            mediatorLiveData.setValue(s + " - emission from observer of liveData2");
        }
    }
)

mediatorLiveData.observe(this, new Observer<String>() {
    @Override
    public void onChanged(String s) {
        Toast.makeText(context, s , Toast.LENGTH_SHORT).show();
    }
});

liveData1.postValue("hello")    // output : hello - emission from observer of liveData1
liveData2.postValue("world")    // output : world - emission from observer of liveData2

You add 2 liveData to mediatorLiveData using addSource() method of mediatorLiveData. The definition of addSource() method is as the following:

addSource(LiveData<S> source, Observer<S> onChanged)

onChanged observer will be called when source value was changed. In this observer, you can emit values into mediatorLiveData(you can invoke setValue(), postValue() methods). In this way, you have 1 mediatorLiveData which listens 2 liveData. When the data hold in liveData1 or liveData2 changes, the observer of mediatorLiveData invoked! Why? Because you made emissions into mediatorLiveData in the second argument of addSource() method of MediatorLiveData.

Solution 4

MediatorLiveData is a subclass of MutableLiveData that can observe other LiveData objects and react to OnChanged events from them.

For example, if you have a LiveData object in your UI that can be updated from a local database or a network, then you can add the following sources to the MediatorLiveData object: A LiveData object associated with the data stored in the database. A LiveData object associated with the data accessed from the network. Your activity only needs to observe the MediatorLiveData object to receive updates from both sources.

MediatorLiveData provides methods to add and remove source -

  • addSource(LiveData source, Observer onChanged)
  • removeSource(LiveData toRemote)

Check official doc here for example - https://developer.android.com/reference/android/arch/lifecycle/MediatorLiveData

A good read on LiveData, check here - https://medium.com/@elye.project/understanding-live-data-made-simple-a820fcd7b4d0

Share:
34,935
Lalit Kushwah
Author by

Lalit Kushwah

Updated on July 08, 2022

Comments

  • Lalit Kushwah
    Lalit Kushwah almost 2 years

    I have searched a lot but not found the crystal clear answer for the questions:

    1. What is the difference between MediatorLiveData and MutableLiveData?

    2. What are the suitable condition to use either of them.

  • Sagar
    Sagar over 5 years
    After researching on some sample projects as well as android developer's official site I found that MutableLiveData should be used only for notifying your UI when observing any data. It would be great if you could provide the official site which states like this. Can you update your answer with the link?
  • Braian Coronel
    Braian Coronel over 4 years
    Thanks @Ariel :)
  • Mohammad Elsayed
    Mohammad Elsayed almost 4 years