なるようになるかも

力は多くの場合、その人の思いを超えない。

SyncResultメモ。

どうせ自分しか使わないアプリなら、Lollipop限定のJobSchedulerでいいんじゃないかなという気がしてきました。

SyncResultの概要

SyncResult | Android Developersより、必要そうな部分を抜粋。完全な情報はリンク先参照

このクラスはSyncManagerへ同期操作の結果を伝達するために利用される。この値に基づいて、SyncManagerは同期の配置(disposition)と、将来的に新しい同期操作をスケジューリングする必要があるかを決定する。

フィールド

type name description
public boolean databaseError ストレージ層の操作に伴うハードエラーがSyncAdapterに発生したことを示すのに利用します。
public long delayUntil リクエストのAccountAuthorityに一致する将来の同期要求が、少なくともこの秒数だけ遅延させる必要があることを示します。
public boolean fullSyncRequested 設定した場合、SyncManagerはリクエストに利用したのと同じAccountAuthorityと同じ(ただし空のextrasのBundle)で即座に同期を要求します。
public final SyncStats stats 同期操作について、追加の統計情報を保持するために利用します。
public final boolean syncAlreadyInProgress SyncAdapterが既に同期操作を実行していることを示すために利用します。必ずしもAccountAuthorityの要求が処理できたわけではありません(?)。(原文:Used to indicate that the SyncAdapter is already performing a sync operation, though not necessarily for the requested account and authority and that it wasn't able to process this request.)
  • syncAlreadyInProgressの翻訳に全然自信がないです。
  • ソフトエラー(通信失敗)とハードエラー(データベースへの書き込み失敗)の2段階でエラーを管理していることが分かります。
  • 上では端折ってますが、"(as defined by the SyncAdapter)"の箇所はSyncAdapterが定義するので、プログラマが制御する必要はなさそうです。逆に言えば上記のフィールドはユーザー側である程度制御する必要があるのだと思います。

SyncStatsの概要

SyncStats | Android Developersより、必要そうな箇所を抜粋。この辺日本語ソースの情報は、50 Android Hacksという翻訳本にちょっとだけ載っているのを確認したくらいで、ドキュメントもtypoが多い…。

雑訳なので、ちゃんとした情報はリンク先参照。

同期操作の結果について、さまざまな統計を記録するのに利用します。SyncManagerSyncResultを経由してこれらへアクセスし、同期の配置(disposition)を決定するため、いくつかの情報を使用しています。

SyncManagerがこれらの値をどう扱うのかについて、更なる議論はSyncResultを参照してください。

フィールド

type name description
public long numAuthExceptions ハードエラー。リクエストで指定されたAccountでの認証に失敗した。問題を解決するために、ユーザーの何らかの操作が必要であることを意味する。
public long numConflictDetectedExceptions ハードエラー。サーバー上のリソースを更新または削除しようとしたとき、回復不能なバージョン競合が発生した。ローカルストレージをクリアして最初からやり直すようユーザーの介入が必要かもしれませんが、サーバーから新しい状態を取得することで解決することが期待される。
public long numIoExceptions ソフトエラー。ネットワークの接続、またはタイムアウトなどの問題が発生した場合など、再試行すれば成功する可能性があるリクエストである。
public long numParseExceptions ハードエラー。サーバーまたはそれ以降のストレージから受信したデータで問題が発生した。
public long numSkippedEntries 何件入力されたか追跡するためのカウンターで、同期操作中にサーバーまたはローカルストアに無視された件数を意味する。解析不能なデータを検出しても、即座に失敗とせず、スキップして次へ進めることを決めた場合。
  • エントリ(numEntries)=挿入件数(numInserts)+更新件数(numUpdates)+削除件数(numDeletes)という解釈でいいんだろうか。これらは"as defined by the SyncAdapter"とあるので、設定してはいけない。
  • numSkippedEntriesはサーバー側起因で解析不能なデータを処理した場合のみ設定するのか、CONFLICT_IGNOREで重複データを無視した場合も含めていいのか説明が曖昧。numSkippedEntriesを加算してるコードを検索しても3件しか出てこない…。
  • numParseExceptionsは詳細な説明と例示が書かれているのですけど、「サーバーから不正なエントリを受信した場合、そのエントリを削除して進捗を進めた上で、エラーが発生したことを記録するためにnumParseExceptionsを加算することができる」という感じで、実装者の判断に委ねる感じ。

同期結果

クリーン、ソフトエラー、ハードエラーの3種の結果になります。

クリーン

何の問題もなく同期に成功したことを意味します。

生成された時点のSyncResult()の結果はクリーンです。

またclear()メソッドを呼び出すことでクリーンにすることができますが、syncAlreadyInProgressが設定されている状態でclear()を呼び出すと、UnsupportedOperationExceptionがスローされます。

ソフトエラー

軽微なエラーが生じたことを意味し、指数バックオフで再試行します。

いずれかがtrueのとき、ソフトエラーと判定されます。

  • numIoExceptions > 0
  • syncAlreadyInProgress

なお、ソフトエラーとハードエラーの条件を同時に満たした場合、ハードエラー扱いになります。

ハードエラー

重篤なエラーが生じていることを意味し、SYNC_EXTRAS_UPLOADフラグが設定されている場合を除き、再試行しません。

いずれかがtrueのとき、ハードエラーと判定されます。

  • numParseExceptions > 0
  • numConflictDetectedExceptions > 0
  • numAuthExceptions > 0
  • tooManyDeletions
  • tooManyRetries
  • databaseError