バックグラウンド処理を管理しよう! WorkManagerの応用的な使い方を解説
一歩進んだAndroidアプリ開発ができる「Android Jetpack」入門 第10回
ワーカーの状態把握とキャンセル処理
最後に、ワーカーをキャンセルする方法を紹介します。
ワーカーの状態把握はLiveDataを利用
前回のワーカーの状態の図1にもあるように、ワーカーがENQUEUED状態、あるいは、RUNNING状態の場合は、キャンセル処理が可能です。そのためには、まず、ワーカーの状態を把握する必要があります。例えば図1のように、ワーカーの実行ボタンとキャンセルボタンを実装するとして、ユーザビリティを考えると、ワーカーの実行前はキャンセルができないようにしておく必要があります。同様に、ワーカーが実行中(RUNNING状態)の場合は図2のように、待機状態(ENQUEUED状態)の場合は図3のように、キャンセルボタンがタップできるようにする必要があります。
このようにワーカーの状態に応じてボタンなどの表示を変更する場合、第4回で紹介したLiveDataとオブザーバを利用するのが便利です。なぜならWorkManagerには、ワーカーの状態が格納されたLiveDataを取得するメソッドがいくつか用意されているからです。このメソッドは、引数に応じて表2のものが存在します。
| メソッドと引数 | 戻り値 |
|---|---|
| getWorkInfoByIdLiveData(UUID id) | LiveData<WorkInfo> |
| getWorkInfosByTagLiveData(String tag) | LiveData<List<WorkInfo>> |
| getWorkInfosForUniqueWorkLiveData(String uniqueWorkName) | LiveData<List<WorkInfo>> |
getWorkInfoByIdLiveData()以外は、引数がワーカーを検索するためのタグ文字列やenqueueUniqueWork()の第1引数で渡したユニークワーカーの識別文字列となっているため、複数のワーカーが存在することになります。そのため、戻り値は、ListのLiveDataとなっています。
一方、getWorkInfoByIdLiveData()はワーカー各々を確実に区別するためのIDを表すUUIDオブジェクトを指定するため、単一のワーカーの状態情報を取得できます。そのため、可能ならば、UUIDを利用します。
このUUIDは、WorkRequestのgetId()メソッド(Kotlinの場合はidプロパティ)を利用して取得できます。例えば、Javaならばリスト7、Kotlinならばリスト8のコードでワーカーの状態のLiveDataを取得できます。
UUID uuId = workRequest.getId(); LiveData<WorkInfo> workInfoLiveData = workManager.getWorkInfoByIdLiveData(uuId);
val workInfoLiveData = workManager.getWorkInfoByIdLiveData(workRequest.id)
ワーカーの状態はWorkInfoから取得
LiveDataのジェネリクスとして指定しているWorkInfoは、まさにワーカーの状態を表すクラスであり、このWorkInfo内の値を利用して、状態に応じた表示処理の分岐などを行なっていきます。そのため、このLiveDataに登録するオブザーバクラスは、Javaならばリスト9、Kotlinならばリスト10のようなコードになります。
private class WorkInfoLiveDataObserver implements Observer<WorkInfo> {
@Override
public void onChanged(WorkInfo workInfo) {
if(workInfo.getState() == WorkInfo.State.ENQUEUED) {
:
}
else if(workInfo.getState() == WorkInfo.State.RUNNING) {
:
}
else if(workInfo.getState() == WorkInfo.State.SUCCEEDED) {
:
}
else if(workInfo.getState() == WorkInfo.State.CANCELLED) {
:
}
}
}
private inner class WorkInfoLiveDataObserver : Observer<WorkInfo> {
override fun onChanged(workInfo: WorkInfo) {
if(workInfo.state == WorkInfo.State.ENQUEUED) {
:
}
else if(workInfo.state == WorkInfo.State.RUNNING) {
:
}
else if(workInfo.state == WorkInfo.State.SUCCEEDED) {
:
}
else if(workInfo.state == WorkInfo.State.CANCELLED) {
:
}
}
}
WorkInfoクラスには、該当するワーカーの現在の状態を取得するgetState()メソッド(Kotlinではstateプロパティ)があり、その値はWorkInfoのメンバenumであるStateとなっています。
よって、リスト9やリスト10のような分岐を記述し、その中で状態に応じた処理を記述します。図1〜図3のボタンの表示切り替えは、このようにしています。
ワーカーをキャンセルするメソッド
ワーカーをキャンセルする場合も、WorkManagerには引数違いでいくつかのメソッドが用意されており、まとめると、表3のとおりです。
| メソッド名 | 内容 |
|---|---|
| cancelAllWork() | 終了していない全てのワーカーをキャンセル |
| cancelAllWorkByTag(String tag) | 引数のタグに該当する全てのワーカーをキャンセル |
| cancelUniqueWork(String uniqueWorkName) | ユニークワーカーを識別文字列で指定してキャンセル |
| cancelWorkById(UUID id) | UUIDを指定して該当ワーカーをキャンセル |
例えばリスト6のように、UniqueKeepRetry識別文字列で起動したユニークワーカーをキャンセルする場合は、JavaでもKotlinでもリスト11のコードになります。このコードだけで、ワーカーがキャンセルされます。
workManager.cancelUniqueWork("UniqueKeepRetry")
もしワーカーがキャンセルされた時の処理をワーカーに定義したい場合は、ワーカークラスにonStopped()メソッドをオーバーライドして処理を記述します。
まとめ
Android Jetpackについて紹介していく本連載の第10回は、いかがでしたでしょうか。
今回は、WorkManagerの2回目として、ワーカーにデータを渡す方法や再実行の制御、複数起動の制御、さらには、ワーカーの状態を把握するとともにキャンセルを行う方法を紹介しました。次回は、WorkManagerを紹介する最後として、繰り返しのワーカーや、ワーカーのチェイン、優先実行のワーカーを紹介します。
この記事は参考になりましたか?
既に会員の方はを行ってください。
- 一歩進んだAndroidアプリ開発ができる「Android Jetpack」入門連載記事一覧
- この記事の著者
-
WINGSプロジェクト 齊藤 新三(サイトウ シンゾウ)
<WINGSプロジェクトについて>有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。 2026年時点での登録メンバは約50名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書、記事多数。 RSS X: @WingsPro_info(公式)、@WingsPro_info/wings(メンバーリスト) Facebook <個人紹介>WINGSプロジェクト所属のテクニカルライター。Web系製作会社のシステム部門、SI会社を経てフリーランスとして独立。屋号はSarva(サルヴァ)。HAL大阪の非常勤講師を兼務。
※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です
-
山田 祥寛(ヤマダ ヨシヒロ)
静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるLaravel実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数。
※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です
この記事は参考になりましたか?
この記事をシェア
