Android Jetpackシリーズ編(二)WorkManager
この記事では、Androidバックグラウンドタスクを柔軟に管理できるJetpackアーキテクチャコンポーネントのWorkManagerについて説明します.
主な特徴後方互換API 14は、API 23+のデバイスにJobScheduler、API 14-22を有するデバイスにBroadcastReceiver+AlarmManagerの組合せ を用いるは、ネットワーク状態や課金状態等の制約条件 を設定することができる.非同期1回または定期タスク を実現計画タスクの有効な監視と管理 は、複数のタスクの並列またはシリアル実行 を実現する.アプリケーションまたはデバイスの再起動により、タスクが を実行することも保証される. Dozeモード等の省電力機能 を保持する.は、バックエンドサービス にログまたは分析を送信することができる.は、アプリケーションデータを定期的にサーバに同期することができる .
コンポーネント
主に、Worker、WorkRequest、Constraints、WorkManager、WorkContinuationから構成されています.
Workerは、バックグラウンドの時間のかかる操作に専念し、パラメータを柔軟に受信し、結果を返すタスク処理オブジェクトです.
抽象クラスでもあり、抽象メソッド
WorkRequestタスクリクエストオブジェクト
同様に抽象クラスであり、システムは私たちに2つの実装クラス、
Constraintsタスク実行条件オブジェクト
設定ネットワーク状態
WorkManagerタスク管理オブジェクトで、タスクの事前開始、リスニング、キャンセルなどの操作が可能
事前開始タスク操作
接続タスクアクション
タスク実行条件の指定
タスクの作成
リスニングタスク
タスクの実行
タスクのキャンセル
WorkMangerの紹介はここまでです.詳細は、公式ドキュメントを参照してください.https://developer.android.com/topic/libraries/architecture/workmanager
主な特徴
コンポーネント
主に、Worker、WorkRequest、Constraints、WorkManager、WorkContinuationから構成されています.
Workerは、バックグラウンドの時間のかかる操作に専念し、パラメータを柔軟に受信し、結果を返すタスク処理オブジェクトです.
抽象クラスでもあり、抽象メソッド
doWork()
があり、すべての論理時間のかかる操作はこのメソッドで実行できます.実行に成功すればResult.success()
に戻り、失敗すればResult.failure()
に戻り、再試行すればResult.retry()
に戻り、結果を返すときに成功または失敗の中で渡すことができます.例えば、Result.success(data)
です.WorkRequestタスクリクエストオブジェクト
同様に抽象クラスであり、システムは私たちに2つの実装クラス、
OneTimeWorkRequest
とPeriodicWorkRequest
を提供し、前者は1回のタスクであり、後者は循環タスクである.実行するタスクBuilder()
を手配し、実行条件setConstraints()
を設定し、タスクに必要なパラメータsetInputData()
を渡すことができるConstraintsタスク実行条件オブジェクト
設定ネットワーク状態
setRequiredNetworkType()
設定電力量が低いsetRequiresBatteryNotLow()
設定充電時にsetRequiresCharging()
を実行するかどうか設定記憶容量が不足しているsetRequiresStorageNotLow()
を実行するかどうかWorkManagerタスク管理オブジェクトで、タスクの事前開始、リスニング、キャンセルなどの操作が可能
事前開始タスク操作
beginWith()
タスクLiveDataオブジェクトgetWorkInfoByIdLiveData()
キャンセルcancelWorkById()
WorkContinuationタスクの継続オブジェクト.このオブジェクトを使用して、タスクの組合せを実行できます.接続タスクアクション
then()
並列接続アクションcombine()
実行アクションenqueue()
単純な使用CompressWorker
を作成し、一言だけ印刷して成功に戻ります.class CompressWorker(context : Context, params : WorkerParameters): Worker(context, params) {
override fun doWork(): Result {
Logger.d("doWork....")
// Indicate success or failure with your return value:
return Result.success()
}
}
タスク実行条件の指定
val constraints = Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED) //
.setRequiresBatteryNotLow(true) //
.setRequiresCharging(true) //
.setRequiresStorageNotLow(true) //
.setRequiresDeviceIdle(true) // , API 23
.build()
タスクの作成
//
val workA = OneTimeWorkRequest.Builder(CompressWorker::class.java).setConstraints(constraints).build()
//
val workB = OneTimeWorkRequest.Builder(MathWorker::class.java)
.setInputData(Data.Builder()
.putInt(MathWorker.KEY_X_ARG, 1)
.putInt(MathWorker.KEY_Y_ARG, 2)
.putInt(MathWorker.KEY_Z_ARG, 3)
.build())
.build()
// 30 , 15 , JobScheduler API
val workC = PeriodicWorkRequest.Builder(CompressWorker::class.java, 30, TimeUnit.MINUTES).build()
MathWorker
クラスclass MathWorker(context : Context, params : WorkerParameters) : Worker(context, params) {
companion object {
// Define the parameter keys:
const val KEY_X_ARG = "X"
const val KEY_Y_ARG = "Y"
const val KEY_Z_ARG = "Z"
// ...and the result key:
const val KEY_RESULT = "result"
}
override fun doWork(): Result {
val x = inputData.getInt(KEY_X_ARG, 0)
val y = inputData.getInt(KEY_Y_ARG, 0)
val z = inputData.getInt(KEY_Z_ARG, 0)
// ...do the math...
val result = myCrazyMathFunction(x, y, z)
//...set the output, and we're done!
val output: Data = Data.Builder().putInt(KEY_RESULT, result).build()
return Result.success(output)
}
private fun myCrazyMathFunction(x: Int, y: Int, z: Int): Int{
return x + y + z
}
}
リスニングタスク
WorkManager.getInstance().getWorkInfoByIdLiveData(workA.id)
.observe({ lifecycle }, { workInfo ->
// Do something with the status
if (workInfo != null && workInfo.state.isFinished) {
Logger.d("workA")
}
})
WorkManager.getInstance().getWorkInfoByIdLiveData(workB.id)
.observe({ lifecycle }, { workInfo ->
// Do something with the status
if (workInfo != null && workInfo.state.isFinished) {
// MathWorker
Logger.d("workE="+workInfo.outputData.keyValueMap[MathWorker.KEY_RESULT])
}
})
WorkManager.getInstance().getWorkInfoByIdLiveData(workC.id)
.observe({ lifecycle }, { workInfo ->
// Do something with the status
Logger.d("workInfo="+workInfo?.state)
if (workInfo != null && workInfo.state.isFinished) {
Logger.d("workInfo="+workInfo.id)
}
})
タスクの実行
//
WorkManager.getInstance().enqueue(workA)
//
WorkManager.getInstance().beginWith(workA).then(workB).enqueue()
//workA workB , workC
WorkManager.getInstance().beginWith(listOf(workA, workB)).then(workC).enqueue()
//workA workB ,workC workD ,chain1 chain2
val chain1 = WorkManager.getInstance().beginWith(workA).then(workB)
val chain2 = WorkManager.getInstance().beginWith(workC).then(workD)
WorkContinuation.combine(listOf(chain1, chain2)).enqueue()
タスクのキャンセル
WorkManager.getInstance().cancelWorkById(workA.id)
WorkMangerの紹介はここまでです.詳細は、公式ドキュメントを参照してください.https://developer.android.com/topic/libraries/architecture/workmanager