Android MediatorLiveData观察者

时间:2017-08-14 17:33:10

标签: android android-livedata

我对以下代码不起作用的原因感到有点困惑:

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!");

2 个答案:

答案 0 :(得分:21)

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

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

这背后的逻辑是“调解员”。在它观察的LiveData对象和数据的最终使用者之间进行调解。因此,调解者是观察者并且可以同时观察,并且当没有活跃的观察者时,addSource的回调不会被调解者触发。

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

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

答案 1 :(得分:1)

我来到这里是因为我的体验或多或少相同,而是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()的{​​{1}}不一定会返回最新的值,除非它被观察到。