【问题标题】:Android MediatorLiveData observerAndroid MediatorLiveData 观察者
【发布时间】:2017-08-14 17:33:10
【问题描述】:

我对为什么下面的代码不起作用有点困惑:

MutableLiveData<String> mutableTest = new MutableLiveData<>();
MediatorLiveData<String> mediatorTest = new MediatorLiveData<>();
mediatorTest.addSource(mutableTest, test -> {
    Timber.d(test);
});
mutableTest.setValue("bla!");

这段代码看起来很简单,但是调试器没有进入回调,控制台也没有记录任何东西......

编辑:这不应该工作吗?

    MutableLiveData<String> mutableTest = new MutableLiveData<>();
    MediatorLiveData<String> mediatorTest = new MediatorLiveData<>();
    mediatorTest.observe(loginActivity, str -> Timber.d(str));
    mediatorTest.addSource(mutableTest, str -> Timber.d(str));
    mutableTest.setValue("bla!");

【问题讨论】:

  • 没有观察到mediatorTest。当没有活跃的观察者时,很多东西都会被跳过。
  • @CommonsWare 在这个例子中,mutableTest 不是可观察者,mediatorTest 不是观察者吗?为什么我需要观察mediatorTest?我找不到可以给我预期结果的简化演示。我认为addSource 应该将侦听器添加到mediatorTest 观察者,其中mutableTest 在第一个参数中作为可观察对象传递,而lambda 在第二个参数中作为回调传递。
  • mediatorTest 既是观察者又是可观察者。毕竟这是一个LiveData,这意味着它是一个可观察的。 “为什么我需要观察 mediatorTest?” -- 必须有东西消耗数据。那是观察者。您有两个 LiveData 对象,但只有一个被观察到。 MediatorLiveData AFAIK 的主要用途是用于转换,转换方法(例如map())返回MediatorLiveData,然后观察它以查看转换结果。
  • FWIW,请参阅 this sample app 了解自定义转换(RxJava 风格的 filter())及其应用程序。我使用MediatorLiveData 观察提供的LiveData,然后下游消费者观察MediatorLiveData。另外,请参阅库中 Transformations 类的源代码。
  • 由于我没有在转换方法之外使用MediatorLiveData 的示例,我建议您回答自己的问题,显示您最终得到的结果(特别是如果这与您的不同)编辑)。

标签: android android-livedata


【解决方案1】:

这个答案很大程度上是对@CommonsWare 在上面评论部分中已经分享的内容的复制。

为了触发 MediatorLiveData 的 addSource 方法的回调,还需要观察 MediatorLiveData 对象本身。

这背后的逻辑是“中介者”在它观察到的 LiveData 对象和数据的最终消费者之间进行调解。因此,中介者同时是一个观察者和可观察者,当没有活动的观察者时,不会为中介者触发addSource 上的回调。

举个例子;根据 Google 的 Android 架构组件,活动或片段可以让观察者观察 ViewModel 上的中介,而中介又可以观察在 ViewModel 中处理的其他 LiveData 对象或对实用程序类的引用。

@CommonsWare 指出使用了公开方法 mapswitchMap 的 Transformation 类,但这些不在我的用例范围内,尽管它们值得一试。

【讨论】:

    【解决方案2】:

    我来这里是因为我有或多或少相同的经历,但不是MediatorLiveData.getValue()。直到我遇到大问题时,我才意识到这是一个问题。我的问题可以这样表述:

    MutableLiveData<String> mutableTest = new MutableLiveData<>();
    MediatorLiveData<String> mediatorTest = new MediatorLiveData<>();
    mediatorTest.addSource(mutableTest, test -> {
        mediatorTest.value = test;
    });
    mutableTest.setValue("bla!");
    mediatorTest.getValue(); // will be null
    

    我知道它有点简化了,但是MediatorLiveData.getValue() 不会包含"bla",这样你永远不会真正知道你是否可以信任getValue(),除非你 100% 确定它是活动的(超过一名观察员)。

    Transformations.map(...)TransformationsswitchMap(...) 的情况相同,其中返回的 getValue() 不一定返回最新值,除非它被观察到。

    【讨论】:

    • :"(有多个观察者)",实际上它应该有更多的观察者。在您的示例中,您的 MediatorLiveData 没有被观察到,因此它的值不会改变,直到它被一些观察者(如活动或片段)观察到。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-20
    • 2023-04-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多