领域的数据同步不一致
我有一个问题,即每次境界我做同样的查询时间有时会返回我不同的数据。目前我正在使用SyncAdapter进行上传。这个想法是我们正试图实现离线模式。领域的数据同步不一致
因此,当用户创建一个项目得到它的加入境界分贝。我通过获取maxId并向其添加1000来手动生成该项目的ID。之后,我将itemID发送到UploadSyncAdapter,在那里获取itemById并将其发送到后端,后端将带有真实ID的项目返回给我。所以之后,我删除旧的项目,并将新项目插入Realm。
在我回去读取数据后,它每隔两次返回一个数组,例如一个大小为115的数据,另一次是大小为116的数组。我甚至用调试器通过ID搜索项目,它真的是一次找到该项目,第二次找不到该项目。但它看起来像重建项目后,项目在那里,它正常工作,或者如果我通过使用即时运行重新运行应用程序。
赞赏任何帮助...
UPDATE 顺便说一句,我使用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中)
经过一番研究后,我发现问题是什么。但如果我错了,请纠正我。我用我的Rx调用中的Subscribers.newThread()替换了Subscribers.io(),现在它工作正常。所以我的理论是:
之前打电话给我UploadAdapter上传更改后的数据我使用的Rx调用与Subscribers.io()来插入数据库中的我的项目。 Subscribers.io()使用线程池来重用线程,或者在需要时创建新线程。所以我们假设它产生了一个叫做“A”的线程。线程获得一个Realm实例(假设Realm快照为“1”)并将创建的项目插入其中。在调用SyncAdapter get之后,它也得到一个具有相同领域快照“1”的新Realm实例。在SyncAdapter完成将数据上传到服务器后,它会删除旧项目,并插入从服务器获取的新项目。因此,在Realm数据更改后,最新的Realm快照现在为“2”。 SyncAdapter将广播发送到完成上载的活动,并且它应该从Realm数据库获取新数据。
对于来自领域我也是用的Rx与Subscribers.io读取数据()。因此,当从Realm请求新数据时,Subscribers.io()在其池中已经有一个线程正在等待被重用,并且线程为“A”。由于此线程是非Looper线程,它不知道Realm数据已更改,它仍使用Realm快照“1”,所以这就是为什么我从Realm获取旧数据的原因。在刷新几次后,Subscribers.io()可能会创建一个新线程,比如线程“B”。
所以线程“B”也得到是一种境界snaphot,这一次,它是最新的快照,所以快照“2”。它会返回正确的数据。
因此,使用Subscribers.newThread()时,它总是创建一个新线程,它总是有最新的境界快照。
下面是关于Subscribers.io()和Subscribers.newThread()之间的差异的链接: Retrofit with Rxjava Schedulers.newThread() vs Schedulers.io()
希望这可以帮助别人!
很好找。这就说得通了。 – EpicPandaForce
我需要查看您的交易代码,您在哪里删除并插入新元素以给出正确的答案。我的猜测是你在后台线程上使用多个事务,而不是评估查询来获取事务内的元素。此外,请确保在完成操作后关闭后台线程上的领域(以便同步适配器的线程),然后重新打开Realm实例以进行下一步操作。 – EpicPandaForce
噢,看,我是对的:多个事务并执行查询来确定事务外的写入参数(虽然很高兴看到'filterTasksByPermission'的代码) – EpicPandaForce
还应该考虑放置'realm。 close()'在'finally {'中。 – EpicPandaForce