WorkManager には、ワーカーの中間進捗状況の設定および監視に関する組み込みのサポートがあります。アプリがフォアグラウンドで実行されているときにワーカーが実行されていた場合、この情報も、WorkInfo
の LiveData
を返す API を使用して、ユーザーに表示できます。
ListenableWorker
が中間進捗状況を保持可能な setProgressAsync()
API をサポートするようになりました。デベロッパーはこの API を使用して、UI で監視可能な中間進捗状況を設定できます。進捗状況は、プロパティのシリアル化可能なコンテナ(input
および output
に似ており、同じ制限を受ける)である Data
型で表されます。
進捗状況情報を監視および更新できるのは、ListenableWorker
が実行されている間だけです。ListenableWorker
の実行完了後にその進捗状況を設定しようとしても無視されます。
進捗状況情報は、getWorkInfoBy…()
または getWorkInfoBy…LiveData()
のいずれかのメソッドを使用して監視することも可能です。これらのメソッドは、Data
を返す新しい getProgress()
メソッドを持つ WorkInfo
のインスタンスを返します。
更新の進行状況
Java で ListenableWorker
または Worker
を使用している場合、setProgressAsync()
API は ListenableFuture<Void>
を返します。更新プロセスで進捗状況情報をデータベースに保存する場合、進捗状況の更新は非同期で行われます。Kotlin では、CoroutineWorker
オブジェクトの setProgress()
拡張関数を使用して進捗状況情報を更新できます。
この例は ProgressWorker
を示しています。Worker
は開始時に進捗状況の値を 0 に設定し、完了時に 100 に更新します。
Kotlin
import android.content.Context
import androidx.work.CoroutineWorker
import androidx.work.Data
import androidx.work.WorkerParameters
import kotlinx.coroutines.delay
class ProgressWorker(context: Context, parameters: WorkerParameters) :
CoroutineWorker(context, parameters) {
companion object {
const val Progress = "Progress"
private const val delayDuration = 1L
}
override suspend fun doWork(): Result {
val firstUpdate = workDataOf(Progress to 0)
val lastUpdate = workDataOf(Progress to 100)
setProgress(firstUpdate)
delay(delayDuration)
setProgress(lastUpdate)
return Result.success()
}
}
Java
import android.content.Context;
import androidx.annotation.NonNull;
import androidx.work.Data;
import androidx.work.Worker;
import androidx.work.WorkerParameters;
public class ProgressWorker extends Worker {
private static final String PROGRESS = "PROGRESS";
private static final long DELAY = 1000L;
public ProgressWorker(
@NonNull Context context,
@NonNull WorkerParameters parameters) {
super(context, parameters);
// Set initial progress to 0
setProgressAsync(new Data.Builder().putInt(PROGRESS, 0).build());
}
@NonNull
@Override
public Result doWork() {
try {
// Doing work.
Thread.sleep(DELAY);
} catch (InterruptedException exception) {
// ... handle exception
}
// Set progress to 100 after you are done doing your work.
setProgressAsync(new Data.Builder().putInt(PROGRESS, 100).build());
return Result.success();
}
}
進捗状況を確認する
進捗状況情報を監視するには、getWorkInfoById
メソッドを使用して WorkInfo
への参照を取得します。
以下に、Kotlin で getWorkInfoByIdFlow
、Java で getWorkInfoByIdLiveData
を使用する例を示します。
Kotlin
WorkManager.getInstance(applicationContext)
// requestId is the WorkRequest id
.getWorkInfoByIdFlow(requestId)
.collect { workInfo: WorkInfo? ->
if (workInfo != null) {
val progress = workInfo.progress
val value = progress.getInt("Progress", 0)
// Do something with progress information
}
}
Java
WorkManager.getInstance(getApplicationContext())
// requestId is the WorkRequest id
.getWorkInfoByIdLiveData(requestId)
.observe(lifecycleOwner, new Observer<WorkInfo>() {
@Override
public void onChanged(@Nullable WorkInfo workInfo) {
if (workInfo != null) {
Data progress = workInfo.getProgress();
int value = progress.getInt(PROGRESS, 0)
// Do something with progress
}
}
});
停止理由の状態を観察する
Worker
が停止した理由をデバッグするには、WorkInfo.getStopReason()
を呼び出して停止理由をログに記録します。
Kotlin
workManager.getWorkInfoByIdFlow(syncWorker.id)
.collect { workInfo ->
if (workInfo != null) {
val stopReason = workInfo.stopReason
logStopReason(syncWorker.id, stopReason)
}
}
Java
workManager.getWorkInfoByIdLiveData(syncWorker.id)
.observe(getViewLifecycleOwner(), workInfo -> {
if (workInfo != null) {
int stopReason = workInfo.getStopReason();
logStopReason(syncWorker.id, workInfo.getStopReason());
}
});
Worker
オブジェクトのライフサイクルと状態について詳しくは、処理の状態をご覧ください。