【发布时间】:2016-08-25 06:26:24
【问题描述】:
我遇到了一个问题,每次我执行相同的查询时,Realm 有时都会返回不同的数据。目前我正在使用 SyncAdapter 进行上传。这个想法是我们正在尝试实现离线模式。
因此,当用户创建一个项目时,它会被添加到 Realm 数据库中。我通过获取 maxId 并向其添加 1000 手动生成该项目的 ID。之后,我将 itemID 发送到 UploadSyncAdapter,在那里我获取 itemById 并将其发送到后端,后端返回具有真实 ID 的项目。所以在那之后我删除了旧项目并将新项目插入到 Realm 中。
在我返回并读取数据后,它每秒返回一次,例如一个大小为 115 的数据数组,另一次是一个大小为 116 的数组。我什至通过 ID 使用调试器搜索项目,它真的找到了一次该项目,第二次没有。但看起来在我重建项目之后,该项目就在那里并且它可以正常工作,或者如果我使用 Instant Run 重新运行应用程序。
任何帮助表示赞赏...
更新 顺便说一句,我正在使用 RXjava 从服务器获取数据,但它正在当前线程(SyncAdapter 线程)上被订阅和观察。
代码如下:
@Override
public void onNext(TaskResponse taskResponse) {
tasksDatabaseManager.deleteTaskById(taskId);
List<Task> tasks = taskResponse.getTaskDataList();
tasksDatabaseManager.insertTasks(tasks);
}
public void deleteTaskById(int taskId){
Realm realm = Realm.getDefaultInstance();
realm.beginTransaction();
RealmResults<Task> rows = realm.where(Task.class).equalTo(ID, taskId).findAll();
rows.deleteAllFromRealm();
realm.commitTransaction();
realm.close();
}
private void copyOrUpdateTasks(List<Task> tasksList){
Realm realm = Realm.getDefaultInstance();
ArrayList<Task> updatedTaskList;
//first initialize task permissions
updatedTaskList = filterTasksByPermission(tasksList);
//initialize custom task data
for (Task task : updatedTaskList) {
initializeTaskCustomFields(task);
}
//save new data
Log.d(TAG, "tasks number before update: " + getTasks().size());
realm.beginTransaction();
realm.copyToRealmOrUpdate(updatedTaskList);
realm.commitTransaction();
realm.close();
Log.d(TAG, "tasks number after update: " + getTasks().size());
}
在 filterTasksByPermission 中,我只是计算了任务的一些权限,但任务正在列表中返回。在 initializeTaskCustomFields 中,我也只是在保存到 Realm 之前计算对象的 2 个字段(这样我也将这些值保存在 Realm 中)
【问题讨论】:
-
我需要查看您在哪里执行删除和插入新元素的事务代码才能给出正确的答案。我的猜测是您在后台线程上使用了多个事务,而不是评估查询以获取事务中的元素。此外,请确保在完成操作后关闭后台线程(即同步适配器的线程)上的 Realm,然后重新打开 Realm 实例以进行下一个操作。
-
哦,看,我是对的:多个事务并执行查询以确定事务之外的写入参数(尽管很高兴看到
filterTasksByPermission的代码)跨度> -
另外,您应该考虑将
realm.close()放入finally {。 -
事实上,在 filterTasksByPermission 中,我也有打开事务并关闭它的情况。但是,如果我有多个事务,如果我每次都提交它们并关闭 Realm,为什么这很重要?
-
因为它是一个非循环线程,因此不会更新它的 Realm 实例。虽然如果您在事务内部而不是在事务外部进行查询,您仍然应该能够看到最新数据。
标签: android database synchronization realm