MediatorLiveData onChanged 没有被调用
MediatorLiveData onChanged not getting called
在我的应用程序中,我正在尝试使用 MediatorLiveData 来监听对实时数据的更改。由于涉及数据库操作,我使用这样的执行程序服务。
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 来查询同一个对象。查询 returns 一个 LiveData。 (如果我此时使用content.getValue(),我得到的是null。)
然后我使用 MediatorLiveData
监听这个 liveData 的变化。不幸的是,永远不会触发 mediatorLiveData 的 onChange 方法。因此日志也没有打印出来。
这是我的内容道class
@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 方法,它会在订阅源之前检查是否附加了任何活动的观察者。
万一有人重新初始化中介者实时数据,将只观察旧对象,不会观察新对象。
也就是说,不要这样做:
观察
myViewModel.observe(....)
正在尝试为中介分配新内存
myMediatorObj = new MediatorLiveData<>(); //这可能是问题。 如果您有这样的行,请尝试删除。
//在这一点之后,任何设置到对象 myMediatorObj 的东西都不会被观察到
如果您尝试重置数据,请传入一些信号 null/empty/rest。
在我的应用程序中,我正在尝试使用 MediatorLiveData 来监听对实时数据的更改。由于涉及数据库操作,我使用这样的执行程序服务。
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 来查询同一个对象。查询 returns 一个 LiveData。 (如果我此时使用content.getValue(),我得到的是null。)
然后我使用 MediatorLiveData
监听这个 liveData 的变化。不幸的是,永远不会触发 mediatorLiveData 的 onChange 方法。因此日志也没有打印出来。
这是我的内容道class
@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 方法,它会在订阅源之前检查是否附加了任何活动的观察者。
万一有人重新初始化中介者实时数据,将只观察旧对象,不会观察新对象。
也就是说,不要这样做:
观察 myViewModel.observe(....)
正在尝试为中介分配新内存 myMediatorObj = new MediatorLiveData<>(); //这可能是问题。 如果您有这样的行,请尝试删除。
//在这一点之后,任何设置到对象 myMediatorObj 的东西都不会被观察到
如果您尝试重置数据,请传入一些信号 null/empty/rest。