公式ドキュメント
まず読む
https://developer.android.com/topic/libraries/architecture/workmanager/
WorkManager APIを使用すると、遅延タスク、非同期タスク、および実行するタイミングを簡単に指定できます。これらのAPIを使用すると、タスクを作成し、即時または適切なタイミングでWorkManagerに渡すことができます。
デバイスAPIレベルやアプリ状態などの要因に基づいて、タスクを実行するための適切な方法を選択します。アプリケーションの実行中にWorkManagerがいずれかのタスクを実行すると、WorkManagerはアプリケーションのプロセス内の新しいスレッドでタスクを実行できます。
あなたのアプリが実行されていない場合、ワークマネージャは、バックグラウンドタスクをスケジュールするための適切な方法を選択します-デバイスのAPIレベルに応じたとの依存関係を含め、ワークマネージャが使用する可能性のある JobScheduler、Firebase JobDispatcherを、かAlarmManager。
まとめると
- 遅延タスク、非同期タスクの実行に使える
- 実行タイミングを指定できる
- 新スレッドでタスクが実行される
- バックグラウンドで実行する
- APIレベルに応じて適切な方法を選択する
- JobScheduler、Firebase JobDispatcher、AlarmManager
準備
AndroidプロジェクトにWorkManagerライブラリを追加
WorkManagerにはcompileSdkバージョン28以上が必要
app/build.gradle
dependencies {
// work managerを追加
def work_version = "1.0.0-alpha09"
implementation "android.arch.work:work-runtime:$work_version"
implementation "android.arch.work:work-runtime-ktx:$work_version"
実装
実装する前に、公式ドキュメントを見てみる
-
Worker
- このクラスをextendし、実行する内容(タスク)を実装する
-
WorkRequest
- 作業の要求を表す
- 自動生成された一意のIDがあり、このIDからキューに入れたタスクをキャンセルしたり、タスクの状態を見ることができる。
- OneTimeWorkRequestまたはPeriodicWorkRequestを使用する
- OneTimeWorkRequestは1回きりの実行、PeriodicWorkRequestは繰り返し実行
- WorkRequestオブジェクトを作成するためのヘルパークラスがWorkRequest.Builder、PeriodicWorkRequest.Builderの2つある
-
WorkManager
- 制約が満たされた後に実行されることが保証されている作業を実行(エンキュー)する
- APIレベル23以上は
JobScheduler
を使用する - APIレベル14-22はFirebase JobDispatcher、またはカスタムAlarmManager + BroadcastReceiver実装を使用する
- 作業はバックグラウンドスレッドで実行される
-
WorkStatus
- 特定のタスクに関する情報が含まれている
-
LiveData
でタスクの状態の観察、完了後の戻り値を取得できる
簡単にまとめると、
Woker
を継承したクラスに動作を書き、
WorkRequest
に制約を準備して、
WorkManager
に実行をお願いし、
WorkStatus
でタスクの状態管理/結果受取ができる。
標準
まずはシンプルに、ボタンを押したらログを出力するだけ
MainActivity
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
//ボタンを押したら
button1.setOnClickListener {
startWorkManager()
}
}
// WorkManagerを実行
private fun startWorkManager() {
val testWorker = OneTimeWorkRequestBuilder<TestWorker>().build()
WorkManager.getInstance().enqueue(testWorker)
}
}
// WorkManagerクラス
class TestWorker(context: Context, params: WorkerParameters) : Worker(context, params) {
override fun doWork(): Result {
// ここに処理内容を書く
Log.d("MainActivity", "WorkManager Test")
return Result.SUCCESS
}
}
監視
監視してログを追加するなら、以下のようにする
//タスクを監視
WorkManager.getInstance().getStatusById(testWorker.id).observe(this, Observer {
if (it == null) return@Observer
Log.d("MainActivity:StatusById", it.toString())
})
制約
以下の制約を作ってみる
- 充電中である
- 端末バッテリーが少なくない(どの程度あればいいのか?)
//制約を作成
val constraints = Constraints.Builder()
.setRequiresCharging(true) //充電中である
.setRequiresBatteryNotLow(true) //バッテリーが少なくない
.build()
//worker requestを作成
val testWorker = OneTimeWorkRequestBuilder<TestWorker>()
.setConstraints(constraints) //制約を追加
.build()
OneTimeWorkRequestBuilderでビルド時に制約を追加してる
キャンセル
キャンセルは不確定で、すでにタスクが実行中/完了している可能性もある
WorkManager.getInstance().cancelWorkById(testWorker.id)