MediatorLiveData和MutableLiveData在MVVM中有什么区别?

98

我搜索了很多,但没有找到关于以下问题的明确答案:

  1. MediatorLiveData 和 MutableLiveData 有什么区别?

  2. 什么情况下适合使用它们中的任何一个。


1
MediatorLiveData是MutableLiveData的子类,用于在多个LiveData实例中并行观察更改的情况。这种情况在文档中得到了最好的解释,可以在此处找到:https://developer.android.com/reference/android/arch/lifecycle/MediatorLiveData。 - TapanHP
4个回答

70

首先,我们需要知道MutableLiveDataMediatorLiveData之间的关系,才能理解它们之间的区别。

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

现在清楚的是,MediatorLiveData是MutableLiveData的子类,因此MediatorLiveData可以访问MutableLiveData以及LiveData的每一个属性。

第一个问题部分回答,其余答案将在第二个问题结束后讨论。

经过对一些示例项目以及Android开发人员官方网站的研究,我发现MutableLiveData应该仅用于观察任何数据时通知您的UI。

例如,您想在两个不同的片段(Fragment1和Fragment2)上显示两个SeekBar,同时希望在从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属性(根据类层次结构)。


3
通过研究一些样本项目以及安卓开发者官方网站,我发现MutableLiveData只应在观察到任何数据时通知您的UI。如果您能提供官方网站并说明这一点,那就太好了。您能否更新您的答案并附上链接? - Sagar
https://developer.android.com/reference/android/arch/lifecycle/MediatorLiveData - Mohammad Elsayed

45

MutableLiveDataLiveData的子类,它公开了setValue和postValue方法(后者是线程安全的),因此您可以向任何活动观察者分派值。

MediatorLiveData 可以观察其他LiveData对象(源)并对其onChange事件作出反应,这将使您控制何时传播事件或执行特定操作。

请查看以下Google示例:

假设我们只想要由liveData1发出的10个值合并到liveDataMerger中。然后,在10个值之后,我们可以停止侦听liveData1,并将其作为源删除。

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

谢谢 @Ariel :) - Braian Coronel

23
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
你可以使用mediatorLiveData的addSource()方法添加两个liveData。addSource()方法的定义如下:
addSource(LiveData<S> source, Observer<S> onChanged)

当源值发生更改时,将调用onChanged观察者。在此观察者中,您可以向mediatorLiveData发出值(您可以调用setValue(),postValue()方法)。通过这种方式,您有一个监听2个liveData的中介者LiveData。当liveData1或liveData2中保存的数据发生更改时,将调用mediatorLiveData的观察者!为什么?因为您在MediatorLiveData的addSource()方法的第二个参数中进行了对mediatorLiveData的发射。


10
MediatorLiveDataMutableLiveData 的子类,可以观察其他 LiveData 对象并对它们的 OnChanged 事件做出反应。
例如,如果您的 UI 中有一个 LiveData 对象,可以从本地数据库或网络更新,那么您可以将以下源添加到 MediatorLiveData 对象中:
1. 与存储在数据库中的数据相关联的 LiveData 对象。 2. 与从网络访问的数据相关联的 LiveData 对象。
您的活动只需要观察 MediatorLiveData 对象,即可从这两个源接收更新。 MediatorLiveData 提供了以下方法来添加和删除源 -
  • addSource(LiveData source, Observer onChanged)
  • removeSource(LiveData toRemote)
点击此处查看示例 关于 LiveData 的更好阅读,请参见 这里

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接