在 Android ContentProvider 中从网络同步时防止网络同步循环

发布于 2024-11-18 14:56:18 字数 404 浏览 3 评论 0原文

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

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

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

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

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

I'm writing my own ContentProvider which will be synced to a web service using a SyncAdapter.

Problem happens when the sync adapter is modifying the content provider's data the provider triggers a network sync when internally calling getContentResolver().notifyChange causing a sync loop.

The notifyChange with the network sync flag is required for when a client application does the modification but should be avoided when the sync adapter is modifying.

How can one, inside a contentprovider, easly tell if it's being used by a client application (which should trigger network sync upon modification) or by a sync adapter (which should not trigger network sync).

Currently I'm using different CONTENT_URI's (sync adapter accesses the data using a CONTENT_URI_NO_SYNC and client apps using a CONTENT_URI) to be able to distinguish between the two types of access and set the network sync flag accordingly.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

紅太極 2024-11-25 14:56:18

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

他们讨论的方法是将一组元数据标志列添加到数据库中。这让我们可以做三件事。

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

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

  3. 最后,它们不要指出,这些标志可以让您了解该行被修改的原因。如果没有设置任何标志并且行发生更改,则一定是由于服务器的更新所致。因此,无需同步到网络。

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

本地更改

  1. 应用程序创建新行。行“创建”标志为真。
  2. ContentProvider 存储该行,看到创建标志,因此它调用 notifyChange(...,true);
  3. 同步到网络 = true(最后一个参数)会导致 SyncAdapter 触发。
  4. SyncAdapter 扫描数据库,查找设置了创建标志的行并执行适当的服务器操作。成功后,SyncAdapter 清除标志。(ContentProvivder 上的行更新)
  5. ContentProvider 看到标志已清除,没有设置任何标志,因此它调用通知更改(...,假);
  6. ContentObserver 看到标志更改,更新为看起来像“同步完成”。

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

远程更改

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

Watch this video about REST API usage in SyncAdapters.

The method they discuss is to add a set of metadata flags columns to the database. This allows us to do 3 things.

  1. The flags themselves allow the SyncAdapter to determine the rows that need changes and what those changes are. How do you tell the difference between a locally created row and a locally modified row? Furthermore how do you know which REST API call to make? If you just delete a row, how does your SyncAdapter know the row to be deleted if the data is now gone? Instead, set the "Should be deleted" flag, and then, when the SyncAdapter runs, it knows to push a delete to the server.

  2. The flags allow your CursorAdapter to modify the view that is created (like adding a Spinner to show that "This row is being synced")

  3. Finally, and this they don't point out, the flags allow you to tell why the row is being modified. If none of the flags are set and the row changes, it must have been because of an update from the server. Therefore, no need to sync to network.

So, the two workflows are as follows:

Local change

  1. App creates new row. Row "create" flag is true.
  2. ContentProvider stores the row, sees create flag and so it calls notifyChange(...,true);
  3. Sync to network = true (the final parameter) causes SyncAdapter to fire.
  4. SyncAdapter scans the database, finds the row with create flag set and performs appropriate server action. After success, SyncAdapter clears the flag.(row update on ContentProvivder)
  5. ContentProvider sees the flag clear, no flags are left set, so it calls notifyChange(...,false);
  6. ContentObservers see the flag change, update to look like "sync finished"

All these steps are equivalent for update / delete -- one flag per syncable row for each of create/update/delete.
Also notice the other win -- what if "Create" fails temporarily? server down... How do you know to retry? -- Simple, you don't clear the "Create" flag and you see it 15 minutes later.

Remote Change

  1. SyncAdapter fires due to periodic sync.
  2. SyncAdapter fetches an update from the server. Pushes changes into the database. Doesn't set any flags. ContentProvider sees the lack of flags, knows the change must have come from the server (or isn't a database change that needs to be pushed to the server), so it calls notifyChange(...,false);
  3. ContentObservers see the content change and so they update with new row data
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文