ワーカーにデータを渡す方法
本連載は、Android Jetpackを紹介しています。前回から3回にわたって、WorkManagerを紹介しています。今回は、前回の続きとして、まず、ワーカーにデータを渡す方法を紹介します。
サンプルデータは、GitHubから参照できます。
データを渡す仕組みの中心「setInputData()メソッド」
前回紹介したサンプルでは、ワーカーはその起動元からデータをもらうことを前提にしていませんでした。もちろん、そのようなワーカーを利用する場合もありますが、起動元からデータをもらわないと処理が実行できない場合もあります。そのような場合にも対応できるように、WorkManagerにはワーカーにデータを渡す専用の仕組みが用意されています。
まず、コードサンプルをみてみると、Javaではリスト1、Kotlinではリスト2のようなコードになります。このコードは、ワーカー側でループ処理を行う際に表示させるメッセージ文字列と、そのループ処理回数を渡すサンプルとなっています。ここで利用するワーカーであるReceiveCountWorkerでは、この2個のデータをもらって処理を行うことを前提としています。
Data.Builder dataBuilder = new Data.Builder(); // (1) dataBuilder.putString("loopMsg", "こんにちは"); // (2) dataBuilder.putInt("loopCount", 13); // (3) Data inputData = dataBuilder.build(); // (4) OneTimeWorkRequest.Builder workRequestBuilder = new OneTimeWorkRequest.Builder(ReceiveCountWorker.class); // (5) workRequestBuilder.setInputData(inputData); // (6) WorkRequest workRequest = workRequestBuilder.build(); // (7)
val dataBuilder = Data.Builder() // (1) dataBuilder.putString("loopMsg", "こんにちは") // (2) dataBuilder.putInt("loopCount", loopCount) // (3) val data = dataBuilder.build() // (4) val workRequestBuilder = OneTimeWorkRequestBuilder<ReceiveCountWorker>() // (5) workRequestBuilder.setInputData(data) // (6) val workRequest = workRequestBuilder.build() // (7)
JavaもKotlinも同じコードであり、ワーカーにデータを渡す仕組みの中心となるのが、(6)のsetInputData()メソッドです。これは、WorkRequestのビルダーのメソッドなので、(5)のコードで取得したビルダーオブジェクトに対してsetInputData()メソッドを実行して、データを渡します。そして、そのビルダーを元に(7)で生成したWorkRequestを利用して、WorkManagerのキュー登録を行えば、ワーカーの方ではデータを受け取れます。
ただし、setInputData()メソッドを利用する場合は、あらかじめその引数であるandroidx.work.Dataオブジェクトを生成しておく必要があります。そのコードが(1)〜(4)です。これらのコードも、Dataオブジェクトをnewするのではなく、Dataオブジェクトを生成するビルダーのインスタンスを生成し、そのビルダーオブジェクトにデータをセットします。リスト1やリスト2では、(1)がビルダーオブジェクトを生成しているコードです。
ビルダーを生成した次は、(2)や(3)のように、put〇〇()メソッドを利用してデータをセットします。この〇〇部分は、セットするデータ型でメソッド名が変わってきます。これらのメソッドの第1引数がデータを識別するキー文字列、第2引数がデータそのものです。
このようにして、データをセットしたビルダーオブジェクトに対し(4)のように、build()メソッドを実行してDataオブジェクトを生成します。
ワーカー内でデータを受け取るコード
次に、ワーカー側でデータを受け取るコードを見ていきましょう。これは、Javaではリスト3、Kotlinではリスト4のようになります。
public class ReceiveCountWorker extends Worker { : public Result doWork() { Data inputData = getInputData(); // (1) String loopMsg = inputData.getString("loopMsg"); // (2) int loopCount = inputData.getInt("loopCount", 30); // (3) : } }
class ReceiveCountWorker(context: Context, workerParams: WorkerParameters) : Worker(context, workerParams) { override fun doWork(): Result { val loopMsg = inputData.getString("loopMsg") // (2) val loopCount = inputData.getInt("loopCount", 30) // (3) : } }
Workerクラス(正確にはその親クラスであるListenableWorkerクラス)には、起動元から渡されたデータを取得できるgetInputData()というのが存在します。リスト3の(1)では、このメソッドを実行してDataオブジェクトを取得しています。
その後は、(2)や(3)のように、get〇〇()メソッドを実行して、データを取り出します。前項で紹介したput〇〇()メソッド同様に、この〇〇は取得するデータ型でメソッド名が変わってきます。引数としては、取得するデータを識別するキー文字列、つまり、put〇〇()メソッドの第1引数と同じものを渡します。
ただ、このget〇〇()メソッドは(2)のgetString()での文字列取得や、getIntArray()のような配列を取得するメソッド以外は、(3)のように第2引数としてデータが存在しない場合の初期値を渡す必要があるので、注意してください。
なお、Kotlinコードでは、getInputData()メソッドの代わりにinputDataプロパティを利用します。そのため、リスト4の(2)や(3)のように、このinputDataプロパティから直接get〇〇()メソッドを利用してデータを受け取ります。