我有一个带有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.numInsertsSyncStats.numUpdates设置为非null值,并且同步不是仅上传的
  • sync没有软错误,但是有一些硬错误,并且它不是仅用于上传的
  • 同步运行超过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()检查之后,它重新安排了同步的时间,而没有任何其他检查。

    现在是问题的第二部分。



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

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

    09-28 06:07