Google は、黒人コミュニティに対する人種平等の促進に取り組んでいます。取り組みを見る

作業チェーンの作成

WorkManager を使用すると、複数の依存タスクを指定し、その実行順序を定義する作業チェーンを作成してキューに登録することができます。この機能は、複数のタスクを特定の順序で実行する必要がある場合に特に便利です。

作業チェーンを作成するには、それぞれ WorkContinuation のインスタンスを返す WorkManager.beginWith(OneTimeWorkRequest) または WorkManager.beginWith(List<OneTimeWorkRequest>) を使用します。

さらに、WorkContinuation を使用し、then(OneTimeWorkRequest) または then(List<OneTimeWorkRequest>) を呼び出して依存関係にある OneTimeWorkRequest インスタンスを追加できます。

WorkContinuation.then(...) は、呼び出されるたびに新しい WorkContinuation のインスタンスを返します。OneTimeWorkRequest インスタンスの List を追加すると、これらのリクエストを並行して実行できる可能性があります。

最後に、WorkContinuation.enqueue() メソッドを使用して、WorkContinuation のチェーンに対して enqueue() を実行します。

たとえば、この例では、3 つの異なるワーカージョブが実行されるように設定されています(同時に実行されることも可能)。これらのワーカーの結果は結合され、キャッシュ ワーカー ジョブに渡されます。最後に、そのジョブの出力がアップロード ワーカーに渡され、その結果がリモート サーバーにアップロードされます。

Kotlin


WorkManager.getInstance(myContext)
   // Candidates to run in parallel
   .beginWith(listOf(plantName1, plantName2, plantName3))
   // Dependent work (only runs after all previous work in chain)
   .then(cache)
   .then(upload)
   // Call enqueue to kick things off
   .enqueue()

Java


WorkManager.getInstance(myContext)
   // Candidates to run in parallel
   .beginWith(Arrays.asList(plantName1, plantName2, plantName3))
   // Dependent work (only runs after all previous work in chain)
   .then(cache)
   .then(upload)
   // Call enqueue to kick things off
   .enqueue();

入力マージツール

OneTimeWorkRequest インスタンスを連結すると、親の作業リクエストの出力が子への入力として渡されます。したがって、上記の例では、plantName1plantName2plantName3 の出力が cache リクエストへの入力として渡されています。

WorkManager では、複数の親の作業リクエストからの入力を管理するために、InputMerger を使用します。

WorkManager が提供する InputMerger には次の 2 種類があります。

  • OverwritingInputMerger: あらゆる入力のすべてのキーを出力に追加しようとします。競合が発生すると、以前に設定したキーを上書きします。

  • ArrayCreatingInputMerger: 入力をマージして、必要に応じて配列を作成しようとします。

より具体的なユースケースがある場合は、InputMerger をサブクラス化することで、独自の入力マージツールを作成できます。

OverwritingInputMerger

OverwritingInputMerger は、デフォルトのマージメソッドです。マージ中にキーの競合がない場合、キーの最新値により、結果の出力データ内の以前のバージョンが上書きされます。

たとえば、植物の入力のそれぞれに個別の変数名("plantName1""plantName2""plantName3")と一致するキーがある場合は、cache ワーカーに渡されるデータには 3 つの Key-Value ペアが含まれます。

3 つのジョブが、チェーンの次のジョブに異なる出力を渡している図。3 つの出力のキーがすべて異なるため、次のジョブは 3 つの Key-Value ペアを受け取ります。

競合がある場合、最後に完了するワーカーが「勝ち」、その値が cache に渡されます。

3 つのジョブが、チェーンの次のジョブに出力を渡している図。この場合、2 つのジョブが同じキーで出力を生成します。その結果、次のジョブは 2 つの Key-Value ペアを受け取り、競合する出力の 1 つが破棄されます。

WorkRequest は並行して実行されるため、実行順序は保証されません。上の例では、plantName1 は最後に書き込まれた値に応じて、"tulip" または "elm" のいずれかの値を保持します。キーが競合する可能性があり、すべての出力データをマージで保持する必要がある場合は、ArrayCreatingInputMerger を使用することをおすすめします。

ArrayCreatingInputMerger

上の例では、すべての植物名ワーカーからの出力を保持する場合、ArrayCreatingInputMerger を使用する必要があります。

Kotlin


val cache: OneTimeWorkRequest = OneTimeWorkRequestBuilder<PlantWorker>()
   .setInputMerger(ArrayCreatingInputMerger::class)
   .setConstraints(constraints)
   .build()

Java


OneTimeWorkRequest cache = new OneTimeWorkRequest.Builder(PlantWorker.class)
       .setInputMerger(ArrayCreatingInputMerger.class)
       .setConstraints(constraints)
       .build();

ArrayCreatingInputMerger は、各キーと 1 つの配列をペアにします。各キーが一意である場合、結果は一連の、要素が 1 つの配列になります。

3 つのジョブが、チェーンの次のジョブに異なる出力を渡している図。次のジョブは、出力キーごとに 1 つずつ、計 3 つの配列が渡されます。各配列には 1 つのメンバーが含まれます。

キーの競合がある場合、一致する値は 1 つの配列にまとめられます。

3 つのジョブが、チェーンの次のジョブに出力を渡している図。この場合、2 つのジョブが同じキーで出力を生成します。次のジョブには、キーごとに 1 つずつ、計 2 つの配列が渡されます。配列の 1 つには、2 つのメンバーが含まれています。これは、このキーを持つ出力が 2 つあったためです。

チェーンの作成と作業のステータス

OneTimeWorkRequest のチェーンは、作業が正常に完了していれば順番に実行されます(つまり、Result.success() を返します)。実行中に、作業リクエストが失敗するかキャンセルされることがあります。この場合、依存する作業リクエストに影響が生じます。

最初の OneTimeWorkRequest が作業リクエスト チェーンでキューに登録されると、後続のすべての作業リクエストは、その最初の作業リクエストの作業が完了するまでブロックされます。

ジョブチェーンを示す図。最初のジョブがキューに登録されると、すべての後続ジョブは、最初のジョブが完了するまでブロックされます。

キューに登録され、作業の制約がすべて満たされると、最初の作業リクエストが開始されます。ルートの OneTimeWorkRequest または List<OneTimeWorkRequest> で作業が正常に完了した場合(つまり、Result.success() を返した場合)、依存する作業リクエストの次のセットがキューに登録されます。

ジョブチェーンを示す図。最初のジョブが成功し、直後の 2 つの後続ジョブがキューに登録されます。残りのジョブは、先行ジョブが完了するまでブロックされます。

各作業リクエストが正常に完了している場合、チェーン内のすべての作業が完了するまで、同じパターンが残りの作業リクエストのチェーン全体に伝わります。これは最も簡単で推奨されるケースですが、エラー状態を処理することも同様に重要です。

ワーカーが作業リクエストを処理している間にエラーが発生した場合は、定義したバックオフ ポリシーに従ってリクエストを再試行できます。チェーンの一部であるリクエストを再試行するということは、そのリクエストに提供された入力データを使用して、そのリクエストが再試行されることを意味します。並行して実行されている作業は影響を受けません。

ジョブチェーンを示す図。ジョブの 1 つが失敗しましたが、バックオフ ポリシーが定義されていました。このジョブは、一定の時間が経過した後に再実行されます。チェーン内の次のジョブは、このジョブが正常に実行されるまでブロックされます。

カスタム再試行戦略の定義の詳細については、再試行とバックオフ ポリシーをご覧ください。

再試行ポリシーが定義されていないか使い果たされている場合、または OneTimeWorkRequestResult.failure() を返すようななんらかの状態に達した場合は、その作業リクエストとすべての依存する作業リクエストが FAILED. としてマークされます。

ジョブチェーンを示す図。1 つのジョブが失敗し、再試行できません。その結果、チェーン内のすべての後続ジョブも失敗します。

OneTimeWorkRequest がキャンセルされたときにも同じロジックが適用されます。依存する作業リクエストも CANCELLED としてマークされ、作業は実行されません。

ジョブチェーンを示す図。1 つのジョブがキャンセルされました。その結果、チェーン内のすべての後続ジョブもキャンセルされます。

作業リクエストが失敗、またはキャンセルされたチェーンに作業リクエストを追加すると、新たに追加された作業リクエストも FAILED または CANCELLED としてマークされます。既存のチェーンの作業を拡張する場合は、ExistingWorkPolicyAPPEND_OR_REPLACE をご覧ください。

作業リクエスト チェーンの作成時に、依存する作業リクエストで再試行ポリシーを定義して、処理がタイムリーに完了するようにします。作業リクエストの失敗により、チェーンが不完全になったり、予期しない状態になったりすることがあります。

詳しくは、作業のキャンセルと中止をご覧ください。