我正在编写自己的ContentProvider,它将使用SyncAdapter同步到Web服务。
当内部调用getContentResolver()。notifyChange导致同步循环时,当同步适配器修改内容提供者的数据时,问题就会发生,提供者会触发网络同步。
当客户端应用程序执行修改时,需要带有网络同步标志的notifyChange,但在同步适配器修改时应避免使用。
如何在内容提供者内部轻松判断客户端应用程序(修改时应触发网络同步)或同步适配器(不应触发网络同步)是否正在使用它。
目前,我正在使用不同的CONTENT_URI(同步适配器使用CONTENT_URI_NO_SYNC访问数据,使用CONTENT_URI访问客户端应用),以便能够区分这两种访问类型,并相应地设置网络同步标记。
答案 0 :(得分:34)
在SyncAdapter
s。
他们讨论的方法是向数据库添加一组元数据标志列。这允许我们做3件事。
标志本身允许SyncAdapter
确定需要更改的行以及这些更改的内容。您如何区分本地创建的行和本地修改的行?此外,您如何知道要进行哪个REST API调用?如果您只是删除行,那么如果数据现已消失,您的SyncAdapter
如何知道要删除的行?相反,设置“应该删除”标志,然后,当SyncAdapter
运行时,它知道将删除推送到服务器。
这些标记允许您的CursorAdapter
修改所创建的视图(例如添加Spinner
以显示“此行正在同步”)
最后,他们没有指出,标志允许你告诉为什么行被修改。如果没有设置任何标志并且行发生更改,则必须,因为服务器发生了更新。因此,无需同步到网络。
因此,两个工作流程如下:
本地更改
notifyChange(...,true);
SyncAdapter
触发。 SyncAdapter
扫描数据库,找到设置了create flag的行并执行适当的服务器操作。成功后,SyncAdapter
会清除该标记。(ContentProvivder
上的行更新)ContentProvider
看到标志清除,没有设置标志,因此它调用notifyChange(...,false); ContentObserver
看到标志更改,更新看起来像“sync finished”所有这些步骤都等同于更新/删除 - 每个可创建行的一个标志用于每个创建/更新/删除。 还要注意另一个胜利 - 如果“创建”暂时失败怎么办?服务器下来...你怎么知道重试? - 简单,你不清除“创建”标志,你会在15分钟后看到它。
远程更改
SyncAdapter
由于定期同步而触发。 SyncAdapter
从服务器获取更新。将更改推送到数据库中。不设置任何标志。 ContentProvider
看到缺少标志,知道更改必须来自服务器(或者不是需要推送到服务器的数据库更改),因此它调用notifyChange(...,false);
ContentObserver
看到内容更改,因此他们会使用新的行数据进行更新