同步SQLite数据库而不会导致多个onChange

时间:2016-04-21 11:10:47

标签: android sqlite android-contentprovider android-contentresolver

我们在应用程序中本地存储了一些项目的服务器状态的副本。当我们从服务器获取新数据时,项目可能已被更改,删除或插入。同步数据时,将从服务器获取所有当前数据。

本地清单:
第1项,进展23
第2项,进展75
第3项,进展88

远程列表:(第2项已删除)
第1项,进展55
第3项,进展88
第4项,进展1(新)

当前解决方案清除表格,然后批量插入所有项目,如下所示:

  // Remove old content (this is to prevent dead items being left)
  mContentResolver.delete(URI_TO_TABLE, null, null);

  // Insert all new items
  // Most existing items are changed in a sync, hence we may just insert them again instead of updating
  final ContentValues[] inserts = new ContentValues[newItems.size()];
  for (int i = 0; i < newItems.size(); i++) {
      inserts[i] = getChallengeContentValues(newItems.get(i));
  }
  mContentResolver.bulkInsert(URI_TO_TABLE, inserts);

这里的问题是我们还使用ContentObserver,每次发送两个onChange()(一个用于删除,一个用于bulkInsert),导致我们的UI在清除表时首先更新,清空我们的列表项目,并在使用新近同步的列表更新后直接再次填充视图。这导致了很多丑陋的眨眼。

有没有得到一个onChange()applyBatch()似乎每次操作生成一个onChange()。你能以某种方式告诉ContentProvider威胁一堆更新吗?

OR还有另一种基本上采用新列表(远程)并将其存储在数据库中的方法吗?

1 个答案:

答案 0 :(得分:0)

正如您所提到的,applyBatch()是正确的方法。为每个添加/更新/删除事务创建ContentProviderOperation,将其存储为ArrayList<ContentProviderOperation> operations并按照applyBatch()个操作运行它们。

http://developer.android.com/reference/android/content/ContentProvider.html#applyBatch%28java.util.ArrayList%3Candroid.content.ContentProviderOperation%3E%29

如果你的表很大并且你不希望有applyBatch()的开销并且需要使用bulkInsert()那么你可以添加某种黑客,就像在删除查询中添加额外的一样指示提供者不要触发notifyDataSetChanged()