SyncManager保留捆绑包多长时间?

时间:2016-02-09 09:03:55

标签: android android-syncadapter

我有一个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会持续多长时间?

文档指出,遇到软错误将导致指数退避,并且同步将在稍后运行。

  • 它会在某个时候被取消吗?多次软错误后?
  • 重启设备后是否会再次入队?

鉴于连接错误并且同步因软错误多次失败:我想知道是否只是将同步请求排入队列,或者我是否必须自己提供某种持久性以确保在某些位置发送请求点。

1 个答案:

答案 0 :(得分:7)

我不得不深入挖掘Android运行时源代码以找到问题的答案。让我们从问题的第一部分开始。

  

它会在某些时候取消[同步]吗?多次软错误后?

答案可能是否定的,直到满足以下条件之一:

  • 同步已取消
  • 通过SyncManager
  • 启动SyncAdapter,您要求ContentResolver.SYNC_EXTRAS_DO_NOT_RETRY不要重新安排同步
  • 您将SyncResult.tooManyRetries设置为true并且同步不是仅限上传
  • 您将SyncResult.tooManyDeletions设置为true,不要将SyncStats.numInsertsSyncStats.numUpdates设置为非空值,并且同步不会仅限上传
  • 同步没有软错误,但有一些硬错误,并且它不是仅限上传
  • 同步运行超过30分钟
  • 同步不使用网络超过1分钟

因此,多个软错误不会取消同步,这就是原因。

处理所有同步事件以SyncManager.SyncHandler.handleMessage()方法开始,并在SyncManager.runSyncFinishedOrCanceledH()方法中继续。 runSyncFinishedOrCanceledH()的第一个参数是SyncResult,可以是null。当同步完成或null服务断开时,它不是SyncAdapter,这是一个软错误。当同步被取消,过期(超过30分钟),不使用网络超过1分钟时,它是null,而在另一种情况下,我并不完全理解。

如果SyncResult不是null并且同步已完成,则SyncManager会尝试通过调用maybeRescheduleSync()来重新安排同步。此方法检查一些标记和同步结果,如ContentResolver.SYNC_EXTRAS_DO_NOT_RETRYSyncResult.tooManyRetries确定是否需要重新安排同步。在SyncManager检查同步完成后出现软错误syncResult.hasSoftError()后,它会重新安排同步而无需任何其他检查。

现在是问题的第二部分。

  

重启设备后,[sync]是否会再次入队?

是的,它会的。在SystemServer初始化时,它会创建ContentService,然后调用其systemReady()方法,该方法会创建SyncManagerSyncManager在其构造函数中创建SyncStorageEngine,其reads all pending operations位于其构造函数including extra bundles中。这就是为什么同步包中允许的一组类型非常有限的原因。当用户启动时,通过调用SyncQueue.addPendingOperations()将所有待处理操作添加到SynqQueue

这个答案是我对Android代码分析的结果,所以我不能保证它100%正确。但您可以将此信息用作您自己研究的起点。