如何实现Sync Adapter网络恢复后仅执行一次并保留最后同步请求?
如何在SyncAdapter中清空旧同步请求,仅保留最后一次?
我太懂你这个痛点了——离线时不管是自动周期性触发多次,还是用户手快点了好几次同步按钮,等网络一恢复,SyncAdapter就会挨个执行所有排队的请求,不仅浪费客户端资源,搞不好还会给服务器造成不必要的压力。而且你还不想锁定按钮限制用户操作,只想让队列里永远只留最后一次同步请求对吧?
给你个简单直接的解决方案:每次发起新同步请求前,先取消当前账号对应权限下所有待执行的同步任务,这样就能保证队列里永远只有最新的那一次请求,不会堆积。
修改你的代码如下:
// 先获取你的目标Account对象(替换成你实际的Account实例) val targetAccount = // 你的Account对象 val syncAuthority = AUTHORITY_PONTOTEL // 关键步骤:取消该账号下所有待执行的同步请求 // 注意:这个方法只会取消还未开始执行的任务,已经在运行的同步不会被中断 ContentResolver.cancelSync(targetAccount, syncAuthority) // 然后正常发起新的同步请求 val syncBundle = Bundle().apply { putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true) putBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, true) putString(SYNC_TRIGGER_SOURCE, SyncManager.FROM_SYNC_CLICK) } ContentResolver.requestSync(targetAccount, syncAuthority, syncBundle)
为什么这个方法有效?
ContentResolver.cancelSync(account, authority)会移除所有处于等待状态的同步任务,已经在执行中的同步不会被打断(如果需要中断正在运行的同步,可以在onPerformSync方法里监听canceled参数,但一般没必要,因为正在运行的任务已经在处理了,我们只需要清空排队的)。- 不管是手动点击按钮还是周期性任务触发,每次执行这段代码都会先清空旧的排队请求,再添加新的,最终网络恢复后只会执行最后一次发起的同步。
额外注意点
- 一定要传入正确的
Account对象,不要传null——如果传null会取消所有账号下该权限的同步请求,可能影响其他用户账号的同步逻辑。 - 如果是周期性同步触发的场景,同样可以把这个取消逻辑加到周期性任务的触发代码里,确保每次自动同步前都清空旧队列。
内容的提问来源于stack exchange,提问作者Tarcisio Wensing
相关产品推荐
相关产品推荐

