Ven*_*tis 5 android rx-java2 android-room
我正在构建一个 Android 应用程序,使用 Android Room 作为持久层和 RxJava 2。
在我的 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);
Run Code Online (Sandbox Code Playgroud)
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);
}
};
Run Code Online (Sandbox Code Playgroud)
这似乎有效。但是,现在我想更新不同类(重复作业)的基础数据。
部分班级:
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());
}
}
Run Code Online (Sandbox Code Playgroud)
因为我在 Stackoverflow 上读到,要实现此功能,两个类都需要使用相同的 DAO 实例,所以我创建了 TaskDataSource 类,它是一个单例,并获得与我在 MainActivity (mTaskViewModel) 中使用的 ViewModel 相同的 TaskDao 实例。
但它仍然不起作用。但是类可以访问数据,但插入、删除或更新不会触发 MainActivity 中订阅者中对 onNext 的调用。
作为参考,以下是缺少的类:
注入.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);
}
}
Run Code Online (Sandbox Code Playgroud)
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();
}
}
Run Code Online (Sandbox Code Playgroud)
和任务视图模型:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
看来继承是罪魁祸首。正如您所看到的,getTasksForDay我正在执行的查询返回一个Flowable<List<Task>>. Task然而,它实际上是一个子类列表。当更改的基础数据不完全相同的类型时,房间查询似乎不会发出。因此,如果您调用updateTask((Questionnaire) task), 则Flowable<List<Task>>不会发出,但当您调用时updateTask((Task) task)它会发出。
| 归档时间: |
|
| 查看次数: |
2196 次 |
| 最近记录: |