我有一个SyncAdapter
的应用程序。除了正常同步之外,我还会触发USER_READ
事件,我只需将Bundle
传递给适配器而不会将其保留:
Bundle settingsBundle = new Bundle();
settingsBundle.putString(SyncAdapter.USER_READ, uid);
ContentResolver.requestSync(account, authority, settingsBundle);
这将在将来的某个时间正确调用我的同步例程。 uid
中设置的每个Bundle
都会触发自己的运行,所有内容都会按预期同步。
如果现在连接不好,或者请求超时,那么我设置了一个软错误:
syncResult.stats.numIoExceptions += 1;
将导致请求稍后重复。这也很好。
这些SyncRequests / Bundles会持续多长时间?
文档指出,遇到软错误将导致指数退避,并且同步将在稍后运行。
鉴于连接错误并且同步因软错误多次失败:我想知道是否只是将同步请求排入队列,或者我是否必须自己提供某种持久性以确保在某些位置发送请求点。
答案 0 :(得分:7)
我不得不深入挖掘Android运行时源代码以找到问题的答案。让我们从问题的第一部分开始。
它会在某些时候取消[同步]吗?多次软错误后?
答案可能是否定的,直到满足以下条件之一:
SyncManager
SyncAdapter
,您要求ContentResolver.SYNC_EXTRAS_DO_NOT_RETRY
不要重新安排同步
SyncResult.tooManyRetries
设置为true
并且同步不是仅限上传SyncResult.tooManyDeletions
设置为true
,不要将SyncStats.numInserts
或SyncStats.numUpdates
设置为非空值,并且同步不会仅限上传因此,多个软错误不会取消同步,这就是原因。
处理所有同步事件以SyncManager.SyncHandler.handleMessage()
方法开始,并在SyncManager.runSyncFinishedOrCanceledH()
方法中继续。 runSyncFinishedOrCanceledH()
的第一个参数是SyncResult
,可以是null
。当同步完成或null
服务断开时,它不是SyncAdapter
,这是一个软错误。当同步被取消,过期(超过30分钟),不使用网络超过1分钟时,它是null
,而在另一种情况下,我并不完全理解。
如果SyncResult
不是null
并且同步已完成,则SyncManager
会尝试通过调用maybeRescheduleSync()
来重新安排同步。此方法检查一些标记和同步结果,如ContentResolver.SYNC_EXTRAS_DO_NOT_RETRY
和SyncResult.tooManyRetries
确定是否需要重新安排同步。在SyncManager
检查同步完成后出现软错误syncResult.hasSoftError()
后,它会重新安排同步而无需任何其他检查。
现在是问题的第二部分。
重启设备后,[sync]是否会再次入队?
是的,它会的。在SystemServer
初始化时,它会创建ContentService
,然后调用其systemReady()
方法,该方法会创建SyncManager
。 SyncManager
在其构造函数中创建SyncStorageEngine
,其reads all pending operations位于其构造函数including extra bundles中。这就是为什么同步包中允许的一组类型非常有限的原因。当用户启动时,通过调用SyncQueue.addPendingOperations()
将所有待处理操作添加到SynqQueue
。
这个答案是我对Android代码分析的结果,所以我不能保证它100%正确。但您可以将此信息用作您自己研究的起点。