GCMNetworkManager から WorkManager への移行

このドキュメントでは、アプリを移行し、GCMNetworkManager ライブラリの代わりに WorkManager クライアント ライブラリを使用してバックグラウンド処理を実行する方法について説明します。アプリでバックグラウンド ジョブのスケジュールを設定するには、WorkManager を使用することをおすすめします。また、API レベル 22 以下を実行する Android デバイスの場合、WorkManager GCM ライブラリを追加することにより、WorkManager が GCM を使用してタスクのスケジュールを設定できるようになります。

WorkManager への移行

アプリで現在 GCMNetworkManager を使用してバックグラウンド処理を実行している場合、WorkManager への移行手順は次のとおりです。

以下の手順は、タスクの定義とスケジュール設定を行う次の GCMNetworkManager のコードを最初に記述することを前提としています。

Kotlin

val myTask = OneoffTask.Builder()
    // setService() says what class does the work
    .setService(MyUploadService::class.java)
    // Don't run the task unless device is charging
    .setRequiresCharging(true)
    // Run the task between 5 & 15 minutes from now
    .setExecutionWindow(5 * DateUtil.MINUTE_IN_SECONDS,
            15 * DateUtil.MINUTE_IN_SECONDS)
    // Define a unique tag for the task
    .setTag("test-upload")
    // ...finally, build the task and assign its value to myTask
    .build()
GcmNetworkManager.getInstance(this).schedule(myTask)

Java

// In GcmNetworkManager, this call defines the task and its
// runtime constraints:
OneoffTask myTask = new OneoffTask.Builder()
    // setService() says what class does the work
    .setService(MyUploadService.class)
    // Don't run the task unless device is charging
    .setRequiresCharging(true)
    // Run the task between 5 & 15 minutes from now
    .setExecutionWindow(
        5 * DateUtil.MINUTE_IN_SECONDS,
        15 * DateUtil.MINUTE_IN_SECONDS)
    // Define a unique tag for the task
    .setTag("test-upload")
    // ...finally, build the task and assign its value to myTask
    .build();
GcmNetworkManager.getInstance(this).schedule(myTask);

この例では、MyUploadService で実際のアップロード処理を定義することを前提としています。

Kotlin

class MyUploadService : GcmTaskService() {
    fun onRunTask(params: TaskParams): Int {
        // Do some upload work
        return GcmNetworkManager.RESULT_SUCCESS
    }
}

Java

class MyUploadService extends GcmTaskService {
    @Override
    public int onRunTask(TaskParams params) {
        // Do some upload work
        return GcmNetworkManager.RESULT_SUCCESS;
    }
}

WorkManager ライブラリを追加する

WorkManager クラスを使用するには、WorkManager ライブラリをビルド依存関係に追加する必要があります。また、JobScheduler をサポートしていないデバイス(つまり、API レベル 22 以下を実行するデバイス)でアプリを実行する場合は、WorkManager GCM ライブラリも追加する必要があります。これにより、WorkManager が GCM を使用してジョブのスケジュールを設定できるようになります。ライブラリの追加方法について詳しくは、WorkManager のスタートガイドをご覧ください。

マニフェストを変更する

GcmNetworkManagerリファレンス ドキュメントに記載されているように、GCMNetworkManager の実装では GcmTaskService のインスタンスをアプリ マニフェストに追加しました。GcmTaskService は受け取ったタスクを確認して、タスクハンドラにタスクを委任します。Worker へのタスクの委任は WorkManager が管理するため、この処理を行うクラスは必要なくなるので、GcmTaskService をマニフェストから削除します。

Worker を定義する

GCMNetworkManager の実装では、OneoffTask または RecurringTask を定義します。これらのクラスでは、実行する必要がある処理のみを指定します。処理の内容は Worker として書き換える必要があります(WorkRequest の定義を参照)。

サンプルの GCMNetworkManager のコードでは myTask タスクを定義しています。WorkManager の同等のコードは次のようになります。

Kotlin

class UploadWorker(context: Context, params: WorkerParameters)
                        : Worker(context, params) {
    override fun doWork() : Result {
        // Do the upload operation ...
        myUploadOperation()

        // Indicate whether the task finished successfully with the Result
        return Result.success()
    }
}

Java

public class UploadWorker extends Worker {

    public UploadWorker(
        @NonNull Context context,
        @NonNull WorkerParameters params) {
        super(context, params);
    }

    @Override
    public Result doWork() {
      // Do the upload operation ...

      myUploadOperation()

      // Indicate whether the task finished successfully with the Result
      return Result.success()
    }
}

GCM タスクと Worker には次のような違いがあります。

  • GCM は TaskParams オブジェクトを使用してパラメータをタスクに渡します。WorkManager が使用する入力データは、タスクの入出力の定義に関する WorkManager のドキュメントで説明されているように、WorkRequest で指定できます。どちらの場合も、タスクで必要な永続型のパラメータが指定された Key-Value ペアを渡すことができます。
  • GcmTaskServiceGcmNetworkManager.RESULT_SUCCESS のようなフラグを返すことにより、成功または失敗したことを通知します。WorkManager の Worker は、ListenableWorker.Result メソッド(ListenableWorker.Result.success() など)を使用し、メソッドの戻り値を返すことによって結果を通知します。
  • 前述のとおり、制約やタグの設定は Worker を定義するときではなく、WorkRequest を作成する次の手順で行います。

WorkRequest のスケジュールを設定する

Worker の定義では、実行する必要がある処理を指定します。処理を実行するタイミングを指定するには、WorkRequest を定義する必要があります。

  1. OneTimeWorkRequest または PeriodicWorkRequest を作成し、タスクを実行するタイミングと処理を特定するためのタグを指定して必要な制約を設定します。
  2. リクエストを WorkManager.enqueue() に渡して、タスクを実行用のキューに登録します。

たとえば、前のセクションでは、OneoffTask を同等の Worker に変換する方法を説明しました。しかし、その Worker には OneoffTask オブジェクトの実行に関する制約とタグを追加しませんでした。制約とタスク ID の設定は、WorkRequest を作成する際に行います。また、ネットワーク接続がない場合はタスクを実行してはならないことも指定します。GCMNetworkManager ではネットワーク接続がデフォルトで必要なため、ネットワーク接続を明示的にリクエストする必要はありません。一方、WorkManager では、ネットワーク接続が必要であるという制約を明確に追加していない限り、ネットワーク接続は必要ありません。WorkRequest を定義したら、WorkManager を通じてキューに登録します。

Kotlin

val uploadConstraints = Constraints.Builder()
    .setRequiredNetworkType(NetworkType.CONNECTED)
    .setRequiresCharging(true).build()

val uploadTask = OneTimeWorkRequestBuilder<UploadWorker>()
    .setConstraints(uploadConstraints)
    .build()
WorkManager.getInstance().enqueue(uploadTask)

Java

Constraints uploadConstraints = new Constraints.Builder()
    .setRequiredNetworkType(NetworkType.CONNECTED)
    .setRequiresCharging(true)
    .build();

OneTimeWorkRequest uploadTask =
        new OneTimeWorkRequest.Builder(UploadWorker.class)
  .setConstraints(uploadConstraints)
  .build();
WorkManager.getInstance().enqueue(uploadTask);

API のマッピング

このセクションでは、GCMNetworkManager の機能および制約を WorkManager の同等の機能および制約にマッピングする方法について説明します。

制約のマッピング

GCMNetworkManager では、タスクの実行タイミングに関する各種制約を設定できます。ほとんどの場合、対応する制約が WorkManager にもあります。このセクションでは、これらの制約について説明します。

GCMNetworkManager タスクに関する制約を設定するには、タスクの Builder オブジェクトで対応するメソッドを呼び出します。たとえば、Task.Builder.setRequiredNetwork() を呼び出してネットワーク要件を設定できます。

WorkManager では Constraints.Builder オブジェクトを作成し、そのオブジェクトのメソッド(Constraints.Builder.setRequiredNetworkType()) など)を呼び出して制約を設定します。次に、Builder を使用して、WorkRequest にアタッチ可能な Constraints オブジェクトを作成します。詳細については、WorkRequest の定義をご覧ください。

GCMNetworkManager の制約 WorkManager の同等の制約 備考
setPersisted() (不要) WorkManager のすべてのジョブがデバイスの再起動後も保持されます。
setRequiredNetwork() setRequiredNetworkType() デフォルトでは、GCMNetworkManager にはネットワーク アクセスが必要ですが、WorkManager には必要ありません。ジョブでネットワーク アクセスが必要な場合は、setRequiredNetworkType(CONNECTED) を使用するか、ネットワークの種類を具体的に設定する必要があります。
setRequiresCharging()

その他のマッピング

制約以外にも、GCMNetworkManager のタスクに適用できる設定があります。このセクションでは、それらの設定を WorkManager のジョブに適用する方法について説明します。

タグ

GCMNetworkManager のすべてのタスクにタグ文字列を設定する必要があります。この文字列を設定するには、Builder の setTag() メソッドを呼び出します。WorkManager のジョブは、WorkManager によって自動的に生成される ID で一意に特定できます。この ID を取得するには、WorkRequest.getId() を呼び出します。また、WorkRequest には必要に応じて 1 つ以上のタグを設定できます。WorkManager ジョブのタグを設定するには、WorkRequest.Builder.addTag() メソッドを呼び出してから、その Builder を使用して WorkRequest を作成します。

GCMNetworkManager では、setUpdateCurrent() を呼び出すことにより、同じタグが付けられた既存のタスクを置き換える必要があるかどうかを指定できます。 WorkManager で同等の操作を行うには、enqueueUniqueWork() または enqueueUniquePeriodicWork() を呼び出してタスクをキューに登録します。これらのメソッドを使用する場合は、ジョブに一意の名前を指定します。また、その名前を持つ保留中のジョブがすでにある場合に WorkManager でリクエストを処理する方法も指定します。詳しくは、一意の処理を実行するをご覧ください。

タスク パラメータ

パラメータを GCMNetworkManager ジョブに渡すには、Task.Builder.setExtras() を呼び出し、パラメータを含む Bundle を渡します。WorkManager では、パラメータに Key-Value ペアを含む Data オブジェクトを WorkManager のジョブに渡すことができます。詳しくは、入力データの割り当てをご覧ください。