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
インスタンスを連結すると、親の作業リクエストの出力が子への入力として渡されます。したがって、上記の例では、plantName1
、plantName2
、plantName3
の出力が cache
リクエストへの入力として渡されています。
WorkManager では、複数の親の作業リクエストからの入力を管理するために、InputMerger
を使用します。
WorkManager が提供する InputMerger
には次の 2 種類があります。
OverwritingInputMerger
: あらゆる入力のすべてのキーを出力に追加しようとします。競合が発生すると、以前に設定したキーを上書きします。ArrayCreatingInputMerger
: 入力をマージして、必要に応じて配列を作成しようとします。
より具体的なユースケースがある場合は、InputMerger
をサブクラス化することで、独自の入力マージツールを作成できます。
OverwritingInputMerger
OverwritingInputMerger
は、デフォルトのマージメソッドです。マージ中にキーの競合がある場合、キーの最新値により、結果の出力データ内の以前のバージョンが上書きされます。
たとえば、植物の入力のそれぞれに個別の変数名("plantName1"
、"plantName2"
、"plantName3"
)と一致するキーがある場合は、cache
ワーカーに渡されるデータには 3 つの Key-Value ペアが含まれます。
競合がある場合、最後に完了するワーカーが「勝ち」、その値が cache
に渡されます。
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 つの配列になります。
キーの競合がある場合、一致する値は 1 つの配列にまとめられます。
チェーンの作成と作業のステータス
OneTimeWorkRequest
のチェーンは、作業が正常に完了していれば順番に実行されます(つまり、Result.success()
を返します)。実行中に、作業リクエストが失敗するかキャンセルされることがあります。この場合、依存する作業リクエストに影響が生じます。
最初の OneTimeWorkRequest
が作業リクエスト チェーンでキューに登録されると、後続のすべての作業リクエストは、その最初の作業リクエストの作業が完了するまでブロックされます。
キューに登録され、作業の制約がすべて満たされると、最初の作業リクエストが開始されます。ルートの OneTimeWorkRequest
または List<OneTimeWorkRequest>
で作業が正常に完了した場合(つまり、Result.success()
を返した場合)、依存する作業リクエストの次のセットがキューに登録されます。
各作業リクエストが正常に完了している場合、チェーン内のすべての作業が完了するまで、同じパターンが残りの作業リクエストのチェーン全体に伝わります。これは最も簡単で推奨されるケースですが、エラー状態を処理することも同様に重要です。
ワーカーが作業リクエストを処理している間にエラーが発生した場合は、定義したバックオフ ポリシーに従ってリクエストを再試行できます。チェーンの一部であるリクエストを再試行するということは、そのリクエストに提供された入力データを使用して、そのリクエストが再試行されることを意味します。並行して実行されている作業は影響を受けません。
カスタム再試行戦略の定義の詳細については、再試行とバックオフ ポリシーをご覧ください。
再試行ポリシーが定義されていないか使い果たされている場合、または OneTimeWorkRequest
が Result.failure()
を返すようななんらかの状態に達した場合は、その作業リクエストとすべての依存する作業リクエストが FAILED.
としてマークされます。
OneTimeWorkRequest
がキャンセルされたときにも同じロジックが適用されます。依存する作業リクエストも CANCELLED
としてマークされ、作業は実行されません。
作業リクエストが失敗、またはキャンセルされたチェーンに作業リクエストを追加すると、新たに追加された作業リクエストも FAILED
または CANCELLED
としてマークされます。既存のチェーンの作業を拡張する場合は、ExistingWorkPolicy の APPEND_OR_REPLACE
をご覧ください。
作業リクエスト チェーンの作成時に、依存する作業リクエストで再試行ポリシーを定義して、処理がタイムリーに完了するようにします。作業リクエストの失敗により、チェーンが不完全になったり、予期しない状態になったりすることがあります。
詳しくは、作業のキャンセルと中止をご覧ください。