【问题标题】:Sync SQLite database without causing multiple onChange同步 SQLite 数据库而不会导致多个 onChange
【发布时间】:2016-04-21 11:10:47
【问题描述】:

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

本地列表:
第 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 威胁一堆更新吗?

或者是否有另一种方法可以基本上获取新列表(远程)并将其存储在数据库中?

【问题讨论】:

    标签: android sqlite android-contentprovider android-contentresolver


    【解决方案1】:

    正如您所提到的,applyBatch() 是正确的做法。为您的每个添加/更新/删除事务创建ContentProviderOperation,将它们存储为ArrayList&lt;ContentProviderOperation&gt; operations,并在单个applyBatch() 操作中运行它们。

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

    如果您的表很大并且您不希望有applyBatch() 的开销并且需要必须使用bulkInsert(),那么您可以添加某种技巧,例如在删除查询中添加额外内容会指示提供者不触发notifyDataSetChanged()

    【讨论】:

      猜你喜欢
      • 2018-03-03
      • 2016-07-01
      • 2012-10-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-14
      • 2016-11-12
      • 1970-01-01
      相关资源
      最近更新 更多