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

WorkRequest の定義

スタートガイドでは、シンプルな WorkRequest を作成してキューに登録する方法を説明しました。

このガイドでは、WorkRequest オブジェクトを定義してカスタマイズし、以下のような一般的なユースケースに対処する方法について説明します。

  • 1 回限りの処理と繰り返し処理のスケジュールを設定する
  • 処理の制約を設定する(Wi-Fi や充電の必要など)
  • 処理の実行の遅延が最小限になるよう保証する
  • 再試行とバックオフの戦略を設定する
  • 入力データを処理に渡す
  • タグを使用して関連する処理をグループ化する

概要

WorkManager では、処理は WorkRequest を介して定義されます。WorkManager で処理のスケジュールを設定するには、まず WorkRequest オブジェクトを作成してキューに登録する必要があります。

Kotlin


val myWorkRequest = ...
WorkManager.getInstance(myContext).enqueue(myWorkRequest)

Java


WorkRequest myWorkRequest = ...
WorkManager.getInstance(myContext).enqueue(myWorkRequest);

WorkRequest オブジェクトには、WorkManager による処理のスケジュール設定と実行に必要なすべての情報が含まれています。これには、処理を実行するために満たす必要がある制約、遅延や繰り返し間隔などのスケジュール設定の情報、再試行の設定のほか、処理が依存している入力データも含まれます。

WorkRequest 自体は抽象基底クラスです。このクラスには、リクエストの作成に使用できる派生実装として、OneTimeWorkRequestPeriodicWorkRequest の 2 つがあります。名前が示すように、OneTimeWorkRequest は繰り返しのない処理のスケジュール設定に便利です。一方、PeriodicWorkRequest は、一定の間隔で繰り返す処理のスケジュール設定に適しています。

1 回限りの処理のスケジュール設定

追加の設定が不要な単純な処理の場合は、静的メソッドの from を次のように使用します。

Kotlin


val myWorkRequest = OneTimeWorkRequest.from(MyWork::class.java)

Java


WorkRequest myWorkRequest = OneTimeWorkRequest.from(MyWork.class);

より複雑な処理には、ビルダーを使用できます。

Kotlin


val uploadWorkRequest: WorkRequest =
   OneTimeWorkRequestBuilder<MyWork>()
       // Additional configuration
       .build()

Java


WorkRequest uploadWorkRequest =
   new OneTimeWorkRequest.Builder(MyWork.class)
       // Additional configuration
       .build();

定期的な処理のスケジュール設定

アプリでは、特定の処理を定期的に実行しなければならない場合があります。たとえば、データのバックアップ、アプリでの最新のコンテンツのダウンロード、ログのサーバーへのアップロードといったタスクです。

以下に、PeriodicWorkRequest を使用して、定期的に実行される WorkRequest オブジェクトを作成する方法を示します。

Kotlin


val saveRequest =
       PeriodicWorkRequestBuilder<SaveImageToFileWorker>(1, TimeUnit.HOURS)
    // Additional configuration
           .build()

Java


PeriodicWorkRequest saveRequest =
       new PeriodicWorkRequest.Builder(SaveImageToFileWorker.class, 1, TimeUnit.HOURS)
           // Constraints
           .build();

この例では、1 時間間隔で処理のスケジュールが設定されています。

間隔は、繰り返しの間の最小時間として定義されます。ワーカーの正確な実行タイミングは、WorkRequest オブジェクトで使用する制約とシステムで実行される最適化に左右されます。

柔軟な実行間隔

処理の性質上、実行タイミングが重要になる場合は、図 1 に示すように、PeriodicWorkRequest が各間隔のフレックス期間内に実行されるように設定できます。

定期的なジョブのフレックス間隔を設定できます。繰り返し間隔と、繰り返し間隔の終わりに一定の時間を指定するフレックス間隔を定義します。WorkManager は、各サイクルのフレックス間隔内のある時点で、ジョブの実行を試みます。

図 1:図は、処理を実行できるフレックス期間のある繰り返し間隔を示しています。

フレックス期間のある定期的な処理を定義するには、PeriodicWorkRequest を作成するときに repeatInterval と一緒に flexInterval を渡します。フレックス期間は repeatInterval - flexInterval から始まり、間隔の最後まで続きます。

以下に、毎時間の最後の 15 分間に実行される定期的な処理の例を示します。

Kotlin


val myUploadWork = PeriodicWorkRequestBuilder<SaveImageToFileWorker>(
       1, TimeUnit.HOURS, // repeatInterval (the period cycle)
       15, TimeUnit.MINUTES) // flexInterval
    .build()

Java


WorkRequest saveRequest =
       new PeriodicWorkRequest.Builder(SaveImageToFileWorker.class,
               1, TimeUnit.HOURS,
               15, TimeUnit.MINUTES)
           .build();

繰り返し間隔は PeriodicWorkRequest.MIN_PERIODIC_INTERVAL_MILLIS 以上で、フレックス間隔は PeriodicWorkRequest.MIN_PERIODIC_FLEX_MILLIS 以上である必要があります。

定期的な処理に対する制約の影響

定期的な処理に制約を適用できます。たとえば、ユーザーのデバイスが充電中の場合にのみ処理が実行されるように、WorkRequest に制約を追加できます。この場合、定義された繰り返し間隔が経過しても、この条件が満たされるまで PeriodicWorkRequest は実行されません。そのため、実行間隔内に条件が満たされない場合、特定の処理の実行が遅延したり、スキップされたりする可能性があります。

処理の制約

制約により、最適な条件が満たされるまで作業が延期されます。WorkManager では以下の制約を使用できます。

NetworkType 処理の実行に必要なネットワークの種類を制約します。(例: Wi-Fi(UNMETERED))。
BatteryNotLow true に設定すると、デバイスが電池残量低下モードになっている場合には処理が実行されません。
RequiresCharging true に設定すると、デバイスが充電中の場合にのみ処理が実行されます。
DeviceIdle true に設定すると、ユーザーのデバイスがアイドル状態になった後にのみ処理が実行されます。これは、ユーザーのデバイスで実行中の他のアプリのパフォーマンス低下を招くような、一括操作を実行する場合に便利です。
StorageNotLow true に設定すると、ユーザーのデバイスの保存容量が少なすぎる場合、処理は実行されません。

一連の制約を作成して処理に関連付けるには、Contraints.Builder() を使用して Constraints インスタンスを作成し、それを WorkRequest.Builder() に割り当てます。

たとえば、次のコードは、ユーザーのデバイスが充電中で、かつ Wi-Fi に接続している場合にのみ実行される WorkRequest を作成します。

Kotlin


val constraints = Constraints.Builder()
   .setRequiredNetworkType(NetworkType.UNMETERED)
   .setRequiresCharging(true)
   .build()

val myWorkRequest: WorkRequest =
   OneTimeWorkRequestBuilder<MyWork>()
       .setConstraints(constraints)
       .build()

Java


Constraints constraints = new Constraints.Builder()
       .setRequiredNetworkType(NetworkType.UNMETERED)
       .setRequiresCharging(true)
       .build();

WorkRequest myWorkRequest =
       new OneTimeWorkRequest.Builder(MyWork.class)
               .setConstraints(constraints)
               .build();

複数の制約が指定されている場合、すべての制約が満たされた場合にのみ処理が実行されます。

処理の実行中に制約が満たされなくなると、WorkManager がワーカーを停止します。その後、すべての制約が満たされると、処理が再試行されます。

処理の遅延

処理に制約がない場合、または処理がキューに登録されたときにすべての制約が満たされている場合、システムはすぐに処理を実行できます。処理をすぐに実行しない場合、最小限の初期遅延の後に処理を開始するよう指定できます。

次の例は、処理がキューに登録されてから 10 分以上経過してからタスクを実行するように設定する方法を示しています。

Kotlin


val myWorkRequest = OneTimeWorkRequestBuilder<MyWork>()
   .setInitialDelay(10, TimeUnit.MINUTES)
   .build()

Java


WorkRequest myWorkRequest =
      new OneTimeWorkRequest.Builder(MyWork.class)
               .setInitialDelay(10, TimeUnit.MINUTES)
               .build();

この例では、OneTimeWorkRequest の初期遅延を設定する方法を示していますが、PeriodicWorkRequest の初期遅延を設定することもできます。その場合、定期的な処理が最初に実行されるときにのみ遅延が発生します。

再試行とバックオフに関するポリシー

WorkManager で処理を再試行する必要がある場合、ワーカーから Result.retry() を返すことができます。その後、バックオフ遅延バックオフ ポリシーに従って処理のスケジュールが変更されます。

  • バックオフ遅延では、最初の試行後に処理を再試行するまでに待機する最小時間を指定します。この値は 10 秒(または MIN_BACKOFF_MILLIS)以上で指定できます。

  • バックオフ ポリシーでは、以降の再試行のバックオフ遅延が経時的にどの程度増加するかを定義します。WorkManager は、LINEAREXPONENTIAL の 2 つのバックオフ ポリシーをサポートしています。

すべての WorkRequest にバックオフ ポリシーとバックオフ遅延があります。デフォルトのポリシーは 10 秒の遅延が発生する EXPONENTIAL ですが、このポリシーは WorkRequest の設定でオーバーライドできます。

以下に、バックオフ遅延とバックオフ ポリシーのカスタマイズ例を示します。

Kotlin


val myWorkRequest = OneTimeWorkRequestBuilder<MyWork>()
   .setBackoffCriteria(
       BackoffPolicy.LINEAR,
       OneTimeWorkRequest.MIN_BACKOFF_MILLIS,
       TimeUnit.MILLISECONDS)
   .build()

Java


WorkRequest myWorkRequest =
       new OneTimeWorkRequest.Builder(MyWork.class)
               .setBackoffCriteria(
                       BackoffPolicy.LINEAR,
                       OneTimeWorkRequest.MIN_BACKOFF_MILLIS,
                       TimeUnit.MILLISECONDS)
               .build();

この例では、最小バックオフ遅延が、最小値の 10 秒に設定されています。ポリシーが LINEAR であるため、再試行間隔は新しい試行ごとに約 10 秒ずつ増加します。たとえば、最初の実行が Result.retry() で終わった場合、10 秒後に再試行されます。以降の試行後に処理が Result.retry() を返し続けた場合、再試行の間隔は 20 秒、30 秒、40 秒と順に増加していきます。バックオフ ポリシーが EXPONENTIAL に設定されている場合、再試行間隔は 20 秒、40 秒、80 秒のように増加していきます。

処理へのタグ付け

すべての WorkRequest には一意の識別子があります。この識別子を使用して後で処理を識別し、処理のキャンセル進行状況のモニタリングを行うことができます。

論理的に関連する処理のグループがある場合は、処理項目にタグ付けすると便利な場合があります。タグ付けをすることで、WorkRequest のグループを一緒に処理できます。

たとえば、WorkManager.cancelAllWorkByTag(String) は、特定のタグを持つすべての WorkRequest をキャンセルします。また、WorkManager.getWorkInfosByTag(String) は、現在の処理の状態を判断するのに使用できる WorkInfo オブジェクトのリストを返します。

次のコードは、「cleanup」タグを処理に追加する方法を示しています。

Kotlin


val myWorkRequest = OneTimeWorkRequestBuilder<MyWork>()
   .addTag("cleanup")
   .build()

Java


WorkRequest myWorkRequest =
       new OneTimeWorkRequest.Builder(MyWork.class)
       .addTag("cleanup")
       .build();

最後に、1 つの WorkRequest に複数のタグを追加できます。内部的には、これらのタグは一連の文字列として保存されます。WorkRequest から、WorkRequest.getTags() を介してタグのセットを取得します。

入力データの割り当て

処理を実行するために、入力データが必要になる場合があります。たとえば、画像のアップロードを行う処理では、入力としてアップロードする画像の URI が必要になります。

入力値は Key-Value ペアとして Data オブジェクトに保存され、WorkRequest で設定できます。WorkManager は、処理の実行時に入力 Data を処理に渡します。Worker クラスは、Worker.getInputData() を呼び出すことで入力引数にアクセスできます。次のコードは、入力データを必要とする Worker インスタンスを作成する方法と、WorkRequest でインスタンスを送信する方法を示しています。

Kotlin


// Define the Worker requiring input
class UploadWork(appContext: Context, workerParams: WorkerParameters)
   : Worker(appContext, workerParams) {

   override fun doWork(): Result {
       val imageUriInput =
           inputData.getString("IMAGE_URI") ?: return Result.failure()

       uploadFile(imageUriInput)
       return Result.success()
   }
   ...
}

// Create a WorkRequest for your Worker and sending it input
val myUploadWork = OneTimeWorkRequestBuilder<UploadWork>()
   .setInputData(workDataOf(
       "IMAGE_URI" to "http://..."
   ))
   .build()

Java


// Define the Worker requiring input
public class UploadWork extends Worker {

   public UploadWork(Context appContext, WorkerParameters workerParams) {
       super(appContext, workerParams);
   }

   @NonNull
   @Override
   public Result doWork() {
       String imageUriInput = getInputData().getString("IMAGE_URI");
       if(imageUriInput == null) {
           return Result.failure();
       }

       uploadFile(imageUriInput);
       return Result.success();
   }
   ...
}

// Create a WorkRequest for your Worker and sending it input
WorkRequest myUploadWork =
      new OneTimeWorkRequest.Builder(UploadWork.class)
           .setInputData(
               new Data.Builder()
                   .putString("IMAGE_URI", "http://...")
                   .build()
           )
           .build();

同様に、Data クラスを使用して戻り値を出力できます。入力データと出力データについて詳しくは、入力パラメータと戻り値のセクションをご覧ください。

次の手順

状態とモニタリングページで、処理の状態と、処理の進行状況のモニタリング方法について詳しく学習します。