我正在使用 SyncAdapter
和 GCM 将后端服务器上的不同类型的更改通知我的应用程序。例如,如果更改 A 在服务器上发生,我会使用名为 change_a 的字段发送推送通知,我通过 ContentResolver.requestSync()
将其传递给 SyncAdapter
。这样,SyncAdapter
就知道要从服务器同步什么。同样,对于更改 B,我发送了一个名为 change_b 的字段。
除一个用异常(exception),这非常有效。我发送了一个 change_a 通知,它调用了 ContentResolver.requestSync()
但是,因为没有网络可用性,SyncAdapter
还没有被调用。如果在那之后,我发送一个 change_b 通知,再次使用新字段调用 ContentResolver.requestSync()
。然后,当网络启动时,SyncAdapter
被调用,但仅使用最新的字段 change_b,因此,它不会同步更改 A。
因此,基本上,ContentResolver.requestSync()
会覆盖之前所有尚未触发 SyncAdapter 的 requestSync()
调用。 SyncAdapter 与发送的最新额外内容一起运行。
一个解决方案是不区分更改 A 和更改 B,并让 SyncAdapter
同步所有内容。但这对于带宽来说是昂贵的。我想控制同步的内容和时间。我可以做些什么来解决这个问题(也许是一个 syncadapter 标志)?
最佳答案
看来我得出了错误的结论。实际上,经过一些进一步的测试,如果 requestSync()
被不同的 extras 调用,SyncAdapter
会被多次调用,针对每个不同的 Bundle。
我的问题出在其他地方。当我收到推送通知时,我会安排一个警报来触发同步请求,并且我会使用带有标志 PendingIntent.FLAG_CANCEL_CURRENT
的 PendingIntent
,这意味着如果另一个在警报响起之前推送通知,警报将被新数据覆盖。因此,如果设备处于离线状态,当它上线时,它会收到所有待处理的推送通知,并且只会设置一个警报,其中包含来自最新推送通知的数据。
我解决这个问题的方法是对每个 PendingIntent 设置不同的操作,这样设置相同类型的新警报就不会覆盖其他类型的警报。
对此的改进是为每种类型的同步添加一个 collapse_key,以便每种推送通知中只有一个被传送到设备。
关于android - SyncAdapter 仅对多个 requestSync() 调用使用最新的附加功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13320107/