在 Android ContentProvider 中从网络同步时防止网络同步循环 [英] Prevent network sync loop when syncing from network in Android ContentProvider

查看:23
本文介绍了在 Android ContentProvider 中从网络同步时防止网络同步循环的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

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

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.

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

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.

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

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).

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

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.

推荐答案

观看此视频,了解 REST API 的用法在 SyncAdapter 中.

Watch this video about REST API usage in SyncAdapters.

他们讨论的方法是向数据库添加一组元数据标志列.这让我们可以做 3 件事.

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

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

  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.

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

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

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

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:

本地变化

  1. 应用创建新行.行创建"标志为真.
  2. ContentProvider 存储行,看到创建标志,因此它调用 notifyChange(...,true);
  3. Sync to network = true(最后一个参数)导致 SyncAdapter 触发.
  4. SyncAdapter 扫描数据库,找到设置了创建标志的行并执行适当的服务器操作.成功后,SyncAdapter 清除标志.(ContentProvivder 上的行更新)
  5. ContentProvider 看到标志清晰,没有标志被设置,所以它调用 notifyChange(...,false);
  6. ContentObservers 看到标志变化,更新为同步完成"
  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"

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

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.

远程更改

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

这篇关于在 Android ContentProvider 中从网络同步时防止网络同步循环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆