私のアプリでは、MediatorLiveDataを使用してライブデータの変更をリッスンしようとしています。 DBオペレーションが関係しているので、このようなexecutorサービスを使用します。
MediatorLiveData<Content> mediatorLiveData = new MediatorLiveData<>();
appExecutors.diskIO().execute(() -> {
long id = contentDao.insert(content);
Log.i("LIVE", id + "");
LiveData<Content> content = contentDao.getContentById(id);
mediatorLiveData.addSource(content, new Observer<Content>() {
@Override
public void onChanged(@Nullable Content content) {
Log.i("LIVE", "FIRED");
}
});
});
まず、新しいコンテンツオブジェクトをデータベースに挿入してみます。挿入したオブジェクトのIDを取得し、次の行でログインします。良いidを取得します。この後、idを使用して同じオブジェクトを照会します。クエリはLiveDataを返します。 (この時点でcontent.getValue()を使用すると、nullが返されます。)
次に、MediatorLiveData
を使用してこのliveDataの変更をリッスンします。残念ながら、mediatorLiveDataのonChangeメソッドは実行されません。したがって、ログも印刷されません。
これは私のコンテンツdaoクラスです
@Dao
public interface ContentDao {
@Insert
long insert(Content content);
@Query("SELECT * FROM my_table WHERE id = :id")
LiveData<Content> getContentById(long id);
}
何が悪いのか理解できません。誰かが助けてください。ありがとう!!
編集:明確にするために、これはコードの外観です。
return new NetworkBoundResource<Content, CreateContent>(appExecutors) {
@Override
protected void saveCallResult(@NonNull CreateContent item) {
//Something
}
@Override
protected boolean shouldCall(@Nullable Content data) {
//Something;
}
@Override
protected LiveData<Content> createDbCall() {
MediatorLiveData<Content> mediatorLiveData = new MediatorLiveData<>();
appExecutors.diskIO().execute(() -> {
long id = contentDao.insert(content);
Log.i("LIVE", id + "");
LiveData<Content> content = contentDao.getContentById(id);
mediatorLiveData.addSource(content, new Observer<Content>() {
@Override
public void onChanged(@Nullable Content c) {
Log.i("LIVE", "FIRED");
mediatorLiveData.removeSource(content);
mediatorLiveData.postValue(c);
}
});
});
return mediatorLiveData;
}
@NonNull
@Override
protected LiveData<ApiResponse<CreateContent>> createCall() {
//Something
}
}.asLiveData();
値はコンストラクタに返されます。
@MainThread
public NetworkBoundResource(AppExecutors appExecutors) {
this.appExecutors = appExecutors;
result.setValue(Resource.loading(null));
//TODO:: Add method to check if data should be saved. This should apply for search data.
LiveData<ResultType> dbSource = createDbCall();
result.addSource(dbSource, data -> {
result.removeSource(dbSource);
if (shouldCall(data)) {
fetchFromNetwork(dbSource);
} else {
result.addSource(dbSource, newData -> setValue(Resource.success(newData)));
}
});
}
説明したように、mediatorLiveDataにアクティブなオブザーバーが接続されていることを確認する必要があります。
AddSourceメソッドを見てみると、ソースにサブスクライブする前にアクティブなオブザーバーがアタッチされているかどうかが確認されます。