我有一个带有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/Bundle可以保留多长时间?
文档指出,遇到软错误将导致指数补偿,并且同步将在一段时间后运行。
假设连接不良,并且同步多次失败并出现软错误:我想知道是否仅使同步请求入队是否足够,或者我是否必须自己提供某种持久性以确保在某个时刻发送请求。
最佳答案
我不得不在Android运行时源中进行一些挖掘,以找到您问题的答案。让我们从问题的第一部分开始。
在满足以下条件之一之前,答案可能是“否”:
SyncManager
不要通过以SyncAdapter
开头ContentResolver.SYNC_EXTRAS_DO_NOT_RETRY
来重新安排同步的时间表SyncResult.tooManyRetries
设置为true
的SyncResult.tooManyDeletions
设置为true
,请勿将SyncStats.numInserts
或SyncStats.numUpdates
设置为非null值,并且同步不是仅上传的因此,多个软错误不会取消同步,这就是原因。
处理所有同步事件以
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()
检查之后,它重新安排了同步的时间,而没有任何其他检查。现在是问题的第二部分。
是的,它会的。
SystemServer
初始化时,将创建 ContentService
,然后调用其 systemReady()
方法,该方法又将创建 SyncManager
。其构造函数中的SyncManager
创建 SyncStorageEngine
,其构造函数reads all pending operations中的including extra bundles。这就是为什么同步 bundle 中允许的一组类型非常有限的原因。当用户启动时,通过调用 SynqQueue
将所有未完成的操作添加到SyncQueue.addPendingOperations()
中。这个答案是我对Android代码进行分析的结果,因此我不能保证它是100%正确的。但是您可以将这些信息用作自己研究的起点。