What is difference between MediatorLiveData and MutableLiveData in MVVM

Я много искал, но не нашел кристально чистый ответ на вопросы:

  1. В чем разница между MediatorLiveData и MutableLiveData?

  2. Каковы подходящие условия для использования любого из них.

3 ответа

Сначала нам нужно узнать, какова связь между MutableLivedata и MediatorLivedata, чтобы понять разницу между ними.

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

Теперь ясно, что MediatorLiveData является подклассом MutableLiveData, поэтому MediatorLiveData может обращаться к каждому свойству MutableLiveData, а также к LiveData.

Вопрос № 1 ответ частично, а остальная часть ответа будет обсуждаться в конце Вопроса №. 2-х ответ.

Изучив некоторые примеры проектов, а также официальный сайт разработчика Android, я обнаружил, что MutableLiveData следует использовать только для уведомления вашего пользовательского интерфейса при просмотре любых данных.

Например, вы хотите отобразить два SeekBars на двух разных фрагментах (Fragment1 и Fragment2), и вы также хотите, чтобы они синхронизировались при работе из Fragment1.

Другой сценарий состоит в том, что у нас есть 2 экземпляра LiveData, назовем их liveData1 и liveData2, и мы хотим объединить их эмиссии в один объект: liveDataMerger (который является объектом MediatorLiveData). Затем liveData1 и liveData2 станут источниками для liveDataMerger, и каждый раз, когда для любого из них вызывается обратный вызов onChanged, мы устанавливаем новое значение в liveDataMerger.

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

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

В этом случае вы не можете использовать MutableLiveData, но, с другой стороны, если вы хотите сравнить данные в первом примере (где MutableLiveData был использован), вы не сможете, потому что вы не сможете использовать свойство addSource (согласно иерархии классов).

MutableLiveData является подклассом LiveData, который предоставляет методы setValue и postValue (второй - потокобезопасный), поэтому вы можете отправить значение любому активному наблюдателю.

MediatorLiveData может наблюдать за другими объектами (источниками) LiveData и реагировать на их события onChange, это даст вам контроль над тем, когда вы хотите распространить событие или сделать что-то конкретное.

Посмотрите на следующий пример Google:

Давайте рассмотрим, что мы хотим, чтобы только 10 значений, излучаемых liveData1, были объединены в liveDataMerger. Затем, после 10 значений, мы можем прекратить прослушивание liveData1 и удалить его как источник.

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);
          }
      }
 });
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

Вы добавляете 2 liveData в mediatorLiveData с помощью метода addSource() mediatorLiveData. Определение метода addSource () следующее:

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

Наблюдатель onChanged будет вызываться при изменении исходного значения. В этом наблюдателе вы можете передавать значения в mediatorLiveData(вы можете вызывать методы setValue(), postValue()). Таким образом, у вас есть 1 mediatorLiveData, который прослушивает 2 liveData. Когда данные, содержащиеся в liveData1 или liveData2, изменяются, вызывается наблюдатель mediatorLiveData! Почему? Потому что вы сделали выбросы в mediatorLiveData во втором аргументе метода addSource () MediatorLiveData.

MediatorLiveData является подклассом MutableLiveData, который может наблюдать за другими объектами LiveData и реагировать на них событиями OnChanged.

Например, если у вас есть объект LiveData в вашем пользовательском интерфейсе, который можно обновить из локальной базы данных или сети, вы можете добавить следующие источники в объект MediatorLiveData: объект LiveData, связанный с данными, хранящимися в базе данных. Объект LiveData, связанный с данными, доступ к которым осуществляется из сети. Ваша деятельность должна только наблюдать объект MediatorLiveData для получения обновлений из обоих источников.

MediatorLiveData предоставляет методы для добавления и удаления источника -

  • addSource (источник LiveData, Observer onChanged)
  • removeSource (LiveData toRemote)

Проверьте официальный документ здесь, например - https://developer.android.com/reference/android/arch/lifecycle/MediatorLiveData

Хорошее чтение на LiveData, проверьте здесь - https://medium.com/@elye.project/understanding-live-data-made-simple-a820fcd7b4d0

MediatorLiveData держать application Объект для обработки некоторых условий. Например: вам может потребоваться обработать некоторые системные службы, такие как LocationManager, Resource. И вы можете доставить dataEvent с помощью MediatorLiveData,MutableLiveData не имеет ни одного члена, как MediatorLiveData является.

Другие вопросы по тегам