15

我对为什么以下代码不起作用感到有些困惑:

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

2 回答 2

33

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

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

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

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

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

于 2017-08-15T00:31:26.343 回答
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(...)and TransformationsswitchMap(...),其中getValue()返回LiveData的不一定返回最新的值,除非它被观察到。

于 2018-04-17T14:11:10.170 回答