web-dev-qa-db-ja.com

Android MediatorLiveDataオブザーバー

次のコードが機能しない理由について少し混乱しています。

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

この回答は、@ CommonsWareが上記のコメントセクションですでに共有している内容の複製です。

MediatorLiveDataのaddSourceメソッドのコールバックをトリガーするには、MediatorLiveDataオブジェクト自体も監視する必要があります。

この背後にあるロジックは、「メディエーター」が監視するLiveDataオブジェクトとデータの最終的なコンシューマーとの間を仲介することです。したがって、メディエーターはオブザーバーであり、同時にオブザーバブルであり、アクティブなオブザーバーが存在しない場合、addSourceのコールバックはメディエーターに対してトリガーされません。

例として; GoogleのAndroidアーキテクチャコンポーネントに従って、ユーティリティクラス。

@CommonsWareは、メソッドmapswitchMapを公開するTransformationクラスの使用を指摘しましたが、チェックする価値はありますが、これらは私のユースケースの範囲内ではありませんでした。

25
Trace

私は多かれ少なかれ同じ経験を持っていたので、代わりに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"_を含まないので、100%確実でない限り、getValue()を信頼できるかどうかは本当にわかりませんアクティブです(複数のoberserverがあります)。

同じ問題がTransformations.map(...)TransformationsswitchMap(...)の場合にも当てはまります。ここで、返されたLiveDatagetValue()は、観察されない限り、最新の値を返すとは限りません。

1
Anigif