我正在使用Android Room作为持久层和RxJava 2构建Android应用。
在我的UI中,我订阅了一个Room dao返回的Flowable:
MainActivity.java
mTaskViewModel.getTasksForDay(SessionManager.getInstance(this).getUser().getId(), CalendarManager.getInstance().getDayString(CalendarManager.getInstance().getSelectedDate()))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(taskModelsSubscriber);
MainActivity中的订阅者
private Subscriber<List<Task>> taskModelsSubscriber = new Subscriber<List<Task>>() {
@Override
public void onSubscribe(Subscription s) {
s.request(Long.MAX_VALUE);
runOnUiThread(new Runnable() {
@Override
public void run() {
mRefreshLayout.setRefreshing(true);
}
});
}
@Override
public void onNext(List<Task> tasks) {
mTasksList = tasks;
scheduleNotifications();
Collections.sort(mTasksList);
runOnUiThread(new Runnable() {
@Override
public void run() {
TaskArrayAdapter taskArrayAdapter = new TaskArrayAdapter(MainActivity.this, mTasksList, SessionManager.getInstance(getApplicationContext()).getUser());
tasksListView.setAdapter(taskArrayAdapter);
mRefreshLayout.setRefreshing(false);
}
});
}
@Override
public void onError(Throwable t) {
Log.d(TAG, t.getMessage());
runOnUiThread(new Runnable() {
@Override
public void run() {
mRefreshLayout.setRefreshing(false);
Toast.makeText(context, R.string.calendar_download_failed, Toast.LENGTH_SHORT).show();
}
});
}
@Override
public void onComplete() {
mRefreshLayout.setRefreshing(false);
}
};
这似乎有效。但是,现在我想更新来自不同类的基础数据(定期作业)。
某些课程:
TaskDataSource dataSource = Injection.provideTaskDataSource(context);
List<String> uuids = new ArrayList<>();
for (Task task : tasks){
try {
task.setUserId(userId);
Task found = dataSource.getTask(task.getUuid(), userId, today, task.getType()).blockingGet();
if (found != null){
dataSource.updateTask(task);
} else {
//Task doesn't exist, insert
dataSource.insertTask(task);
}
uuids.add(task.getUuid());
} catch(NoSuchElementException ex) {
Log.d(TAG, ex.getMessage());
}
}
因为我在Stackoverflow上的某处读到了为了使它工作,所以两个类都需要使用相同的DAO实例,我创建了TaskDataSource类,它是一个Singleton,并获得与我在MainActivity中使用的ViewModel相同的TaskDao实例。 (mTaskViewModel)。
但它仍然无效。但是类可以访问数据,但插入,删除或更新数据不会触发对MainActivity中订阅服务器的onNext的调用。
供参考,以下是缺少的课程:
Injection.java
public class Injection {
public static UserDataSource provideUserDataSource(Context context) {
DeliciousDatabase database = DeliciousDatabase.getInstance(context);
return new LocalUserDataSource(database.userDao());
}
public static TaskDataSource provideTaskDataSource(Context context) {
//DeliciousDatabase database = DeliciousDatabase.getInstance(context);
return LocalTaskDataSource.getInstance(context);
}
public static ViewModelFactory provideViewModelFactory(Context context) {
UserDataSource userDataSource = provideUserDataSource(context);
TaskDataSource taskDataSource = provideTaskDataSource(context);
return new ViewModelFactory(userDataSource, taskDataSource);
}
}
LocalTaskDataSource(实现TaskDataSource)
public class LocalTaskDataSource implements TaskDataSource {
private final TaskDao mTaskDao;
private static LocalTaskDataSource mInstance;
private LocalTaskDataSource(TaskDao taskDao) {
mTaskDao = taskDao;
}
public static LocalTaskDataSource getInstance(Context context) {
if(mInstance == null) mInstance = new LocalTaskDataSource(DeliciousDatabase.getInstance(context).taskDao());
return mInstance;
}
@Override
public Flowable<List<Task>> getTasksForDay(String userId, String day) {
return Maybe.zip(
mTaskDao.getQuestionnairesForDay(userId, day),
mTaskDao.getPhysicalTestsForDay(userId, day),
mTaskDao.getSpeechTestsForDay(userId, day),
mTaskDao.getStressTestsForDay(userId, day),
mTaskDao.getPlateControlsForDay(userId, day),
mTaskDao.getWeeklyFeedbacksForDay(userId, day),
(questionnaires, physicalTests, speechTests, stressTests, plateControls, weeklyFeedbacks) -> {
List<Task> combined = new ArrayList<>();
combined.addAll(questionnaires);
combined.addAll(physicalTests);
combined.addAll(speechTests);
combined.addAll(stressTests);
combined.addAll(plateControls);
combined.addAll(weeklyFeedbacks);
return combined;
}
).toFlowable();
}
}
和TaskViewModel:
public class TaskViewModel extends ViewModel {
private final TaskDataSource mDataSource;
private List<Task> mTasks;
public TaskViewModel(TaskDataSource dataSource) {
mDataSource = dataSource;
}
public Flowable<List<Task>> getTasksForDay(String userId, String day) {
return mDataSource.getTasksForDay(userId, day);
}
public Maybe<? extends Task> getTask(int id, Task.Type type) {
return mDataSource.getTaskById(id, type);
}
public void updateTask(Task task) {
mDataSource.updateTask(task);
}
public Maybe<List<TaskStats>> getWeeklyStatistics(long start, long end) {
return mDataSource.getWeeklyStatistics(start, end);
}
}
答案 0 :(得分:2)
似乎继承是罪魁祸首。如您所见,我正在执行的getTasksForDay
查询返回Flowable<List<Task>>
。但是,它实际上是Task
子类的列表。当更改的基础数据类型不完全相同时,似乎不会发出Room查询。因此,如果您致电updateTask((Questionnaire) task)
,则Flowable<List<Task>>
不会发出,但是当您拨打updateTask((Task) task)
时,它会发出。