在 Android 内容提供程序中从网络同步时防止网络同步循环

我正在编写自己的ContentProvider,它将使用SyncAdapter同步到Web服务。

当同步适配器修改内容提供程序的数据时,会发生问题,提供程序在内部调用 getContentResolver().notifyChange 导致同步循环时触发网络同步。

当客户端应用程序执行修改时,需要使用带有网络同步标志的 notifyChange,但在修改同步适配器时应避免使用。

在内容提供商内部,如何能够轻松判断客户端应用程序(应在修改时触发网络同步)还是同步适配器(不应触发网络同步)正在使用它。

目前,我正在使用不同的CONTENT_URI(同步适配器使用CONTENT_URI_NO_SYNC访问数据,使用CONTENT_URI访问客户端应用程序)来区分两种类型的访问并相应地设置网络同步标志。


答案 1

观看此视频,了解 REST API 在 中的使用情况。SyncAdapter

他们讨论的方法是向数据库中添加一组元数据标志列。这使我们能够做3件事。

  1. 标志本身允许 确定需要更改的行以及这些更改是什么。如何区分本地创建的行和本地修改的行?此外,您如何知道要进行哪个 REST API 调用?如果您只是删除一行,如果数据现在消失了,您如何知道要删除的行?相反,设置“应删除”标志,然后,当运行时,它知道将删除推送到服务器。SyncAdapterSyncAdapterSyncAdapter

  2. 这些标志允许您修改创建的视图(例如添加 a 以显示“此行正在同步”)CursorAdapterSpinner

  3. 最后,他们没有指出这点,这些标志允许您告诉为什么行被修改。如果未设置任何标志,并且行发生更改,则一定是由于服务器的更新。因此,无需同步到网络。

因此,这两个工作流如下所示:

本地更改

  1. 应用创建新行。行“创建”标志为真。
  2. ContentProvider 存储行,看到创建标志,因此它调用notifyChange(...,true);
  3. 同步到网络 = true(最后一个参数)导致触发。SyncAdapter
  4. SyncAdapter扫描数据库,查找设置了 create 标志的行并执行相应的服务器操作。成功后,清除标志。(行更新于SyncAdapterContentProvivder)
  5. ContentProvider看到标志清除,没有标志被设置,所以它调用通知Change(...,false);
  6. ContentObservers 看到标志更改,更新为“同步完成”

所有这些步骤都等效于更新/删除 - 对于创建/更新/删除的每个可同步行,每个标志都有一个标志。还要注意另一个胜利 - 如果“创建”暂时失败怎么办?服务器关闭...您如何知道重试?- 很简单,你不清除“创建”标志,15分钟后你会看到它。

远程更改

  1. SyncAdapter由于定期同步而触发。
  2. SyncAdapter从服务器获取更新。将更改推送到数据库中。不设置任何标志。 看到缺少标志,知道更改必须来自服务器(或者不是需要推送到服务器的数据库更改),因此它调用ContentProvidernotifyChange(...,false);
  3. ContentObservers 看到内容更改,因此它们使用新的行数据进行更新

答案 2

推荐