What is difference between MediatorLiveData and MutableLiveData in MVVM
Я много искал, но не нашел кристально чистый ответ на вопросы:
В чем разница между MediatorLiveData и MutableLiveData?
Каковы подходящие условия для использования любого из них.
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
является.