14

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

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

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

在 contentprovider 中,如何轻松判断它是由客户端应用程序(应在修改时触发网络同步)还是由同步适配器(不应触发网络同步)使用。

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

4

1 回答 1

34

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

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

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

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

  3. 最后,他们没有指出这一点,标志可以让您知道为什么要修改该行。如果没有设置任何标志并且行发生更改,则一定是因为来自服务器的更新。因此,无需同步到网络。

因此,两个工作流程如下:

局部变化

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

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

远程更改

  1. SyncAdapter由于周期性同步而触发。
  2. SyncAdapter从服务器获取更新。将更改推送到数据库中。不设置任何标志。 ContentProvider看到缺少标志,知道更改必须来自服务器(或者不是需要推送到服务器的数据库更改),所以它调用notifyChange(...,false);
  3. ContentObservers 看到内容的变化,所以他们用新的行数据更新
于 2011-07-06T20:37:09.590 回答