2016-02-09 6 views
10

Ich habe eine Anwendung mit einer SyncAdapter. Zusätzlich zu der normalen Synchronisation auslösen ich eine USER_READ Ereignis, mit dem ich eine Bundle an den Adapter nur passieren, ohne es zu persistierenden:Wie lange werden Pakete vom SyncManager beibehalten?

Bundle settingsBundle = new Bundle(); 
settingsBundle.putString(SyncAdapter.USER_READ, uid); 
ContentResolver.requestSync(account, authority, settingsBundle); 

Dies wird in Zukunft richtig irgendwann meine Synchronisationsroutine aufrufen. Jeder uid, der in Bundle gesetzt ist, löst seinen eigenen Lauf aus und alles wird wie erwartet synchronisiert.

Wenn jetzt die Verbindung schlecht ist, oder die Anforderung mal, dann setze ich einen weichen Fehler:

syncResult.stats.numIoExceptions += 1; 

, die die Anforderung verursacht später wiederholt werden. Das funktioniert auch gut.


Wie lange diese SyncRequests/Bundles beibehalten werden?

Die Dokumentation besagt, dass das Auftreten eines Soft-Fehlers einen exponentiellen Backoff verursacht und dass die Synchronisation einige Zeit später ausgeführt wird.

  • Wird es irgendwann abgebrochen? Nach mehreren weichen Fehlern?
  • Wird es nach einem Neustart des Geräts erneut in die Warteschlange eingereiht?

die Verbindung ist schlecht, und die Synchronisation schlägt fehl Bei mehrfach mit Soft-Fehlern: mich würde ich gerne wissen, ob nur eine Synchronisationsanforderung Einreihen genug ist, oder wenn ich bieten irgendeine Art von Beharrlichkeit seiner Anforderungen, um sicherzustellen, irgendwann gesendet.

+0

Es hängt von Ihrer Anforderung ab, dass es sein wird Wenn das System sendet eine Netzwerkmeldung, in regelmäßigen Abständen, auf Anforderung wie nach einem Neustart des Geräts lesen Sie http://developer.android.com/training/sync-adapters /running-sync-adapter.html –

+0

@WaqasAhmed Danke, ja. Ich kenne die Dokumentation. Ich frage mich nur, wie lange diese Anfragen andauern werden, besonders wenn ich nicht nur * Full Sync * verwende, sondern auch die Daten aus den Bundles brauche. –

Antwort

7

Ich musste in Android-Laufzeitquelle ein wenig graben, um eine Antwort auf Ihre Frage zu finden. Beginnen wir mit dem ersten Teil der Frage.

Will it [sync] be canceled at some point? After multiple soft errors?

Und die Antwort ist wahrscheinlich nein, bis eine der folgenden Bedingungen erfüllt ist:

  • Synchronisierung abgebrochen
  • Sie fragen SyncManager nicht synchron zur Umschuldung von SyncAdapter mit ContentResolver.SYNC_EXTRAS_DO_NOT_RETRY
  • Start Sie setzen SyncResult.tooManyRetries zu true und die Synchronisierung ist nicht nur zum Hochladen
  • Sie setzen SyncResult.tooManyDeletions zu true, nicht setzen SyncStats.numInserts oder SyncStats.numUpdates auf Nicht-Null-Werte, und die Synchronisierung nicht Upload-
  • sync keine weiche Fehler hat aber einige harte Fehler hat, und es ist nicht Upload-
  • Sync läuft für mehr als 30 Minuten
  • Sync-Netzwerk nicht länger als 1
  • Minuten verwenden

So mehrere weiche Fehler abbrechen nicht synchronisieren und hier ist der Grund.

Die Verarbeitung aller Synchronisierungsereignisse beginnt in SyncManager.SyncHandler.handleMessage() Methode und wird in SyncManager.runSyncFinishedOrCanceledH() Methode fortgesetzt. Das erste Argument von runSyncFinishedOrCanceledH() ist SyncResult, das null sein kann. Es ist nicht null entweder, wenn die Synchronisation beendet ist oder wenn SyncAdapter Service unterbrochen ist, was ein weicher Fehler ist. Und es ist null, wenn die Synchronisierung abgebrochen wird, abgelaufen ist (mehr als 30 Minuten), Netzwerk für mehr als 1 Minute nicht verwendet, und in einem anderen Fall verstehe ich nicht vollständig.

Bei SyncResult nicht null und Synchronisierung mit Fehlern beendet ist, versucht SyncManager sync neu zu planen, indem maybeRescheduleSync() Aufruf. Diese Methode überprüft einige Flags und Sync-Ergebnisse, wie ContentResolver.SYNC_EXTRAS_DO_NOT_RETRY und SyncResult.tooManyRetries entscheiden, ob es die Synchronisierung neu planen muss. Und nach SyncManager überprüft, ob die Synchronisierung mit einem weichen Fehler abgeschlossen ist, verschiebt es Synchronisierung ohne zusätzliche Prüfungen neu.

Und jetzt der zweite Teil der Frage.

Will it [sync] be enqueued again after a reboot of the device?

Ja, wird es. Wenn SystemServer initialisiert wird, erstellt es ContentService und ruft dann seine systemReady()-Methode auf, die wiederum SyncManager erstellt. SyncManager in seinem Konstruktor erstellt SyncStorageEngine, die reads all pending operations in seinem Konstruktor including extra bundles. Aus diesem Grund ist eine Reihe von Typen, die in Synchronisierungsbündeln zulässig sind, sehr begrenzt. Und wenn der Benutzer gestartet wird, werden alle ausstehenden Operationen zu SynqQueue hinzugefügt, indem SyncQueue.addPendingOperations() aufgerufen wird.

Diese Antwort ist das Ergebnis meiner Analyse von Android-Code, so kann ich nicht garantieren, dass es 100% korrekt ist. Aber Sie können diese Informationen als Ausgangspunkt für Ihre eigene Forschung verwenden.

+0

Das war die Antwort, nach der ich gesucht habe, danke! –