4

我正在使用 aSyncAdapter和 GCM 来通知我的应用程序后端服务器上的不同类型的更改。例如,如果更改 A 发生在服务器上,我会使用名为 change_a 的字段进行推送通知,并将其传递给SyncAdapterthrough ContentResolver.requestSync()。这样,SyncAdapter知道从服务器同步什么。同样,对于更改 B,我发送一个名为 change_b 的字段。

除了一个用例外,这非常有效。我发送了一个 change_a 通知,它会调用ContentResolver.requestSync(),但是因为没有网络可用,所以SyncAdapter还没有调用。如果在那之后,我发送一个 change_b 通知,再次ContentResolver.requestSync()使用新字段调用。然后,当网络启动时,SyncAdapter会调用,但仅使用最新的字段 change_b,因此,它不会同步更改 A。

因此,基本上,ContentResolver.requestSync()覆盖所有requestSync()尚未触发 SyncAdapter 的先前调用。SyncAdapter 使用已发送的最新附加功能运行。

对此的一种解决方案是不区分更改 A 和更改 B 并SyncAdapter同步所有内容。但这对带宽来说是昂贵的。我想控制同步的内容和时间。我可以做些什么来解决这个问题(可能是一个同步适配器标志)?

4

2 回答 2

3

看来我得出了错误的结论。实际上,经过进一步的测试,如果requestSync()使用不同的附加功能调用 if ,SyncAdapter则会针对每个不同的 Bundle 调用多次。

我的问题出在其他地方。当我收到推送通知时,我会安排一个警报来触发同步请求,我会使用PendingIntent带有标志的 a PendingIntent.FLAG_CANCEL_CURRENT,这意味着如果在警报响起之前有另一个推送通知出现,警报将被新数据覆盖. 因此,如果设备处于离线状态,当它上线时,它会收到所有待处理的推送通知,并且只会设置一个警报,其中包含最新推送通知中的数据。

我解决此问题的方法是在每个 PendingIntent 上设置不同的操作,以便设置相同类型的新警报不会覆盖其他类型的警报。

对此的改进是为每种类型的同步添加一个collapse_key,以便每种推送通知中只有一个被传递到设备。

于 2012-11-11T09:40:46.043 回答
1

看来我得出了错误的结论。实际上,经过进一步的测试,如果 requestSync() 使用不同的 extra 调用,则 SyncAdapter 会针对每个不同的 Bundle 调用多次。

如果您在多次调用中使用不同的附加功能requestSync(),则将performSync()为每个调用requestSync()。我想添加证明:SyncOperation.javatoKey()中的调用合并了 extras Bundle 中的值。这可以防止重复这些.SyncManagerSyncOperations

于 2013-10-30T21:41:22.907 回答