WorkManager에는 작업자의 중간 진행률을 설정하고 관찰하기 위한 기본 지원이 있습니다. 앱이 포그라운드에 있을 때 worker가 실행 중이면 WorkInfo의 LiveData를 반환하는 API를 사용하여 이 정보를 사용자에게 표시할 수도 있습니다.
이제 ListenableWorker에서 setProgressAsync() API를 지원합니다. 이는 중간 진행률을 유지하는 데 사용됩니다. 개발자는 이러한 API를 사용하여 UI에서 관찰할 수 있는 중간 진행률을 설정할 수 있습니다.
진행률은 Data 유형으로 표시되며 이 유형은 속성의 직렬화 컨테이너입니다(input 및 output과 유사하며 동일한 제한사항이 적용됨).
진행률 정보는 ListenableWorker 실행 중에만 관찰하고 업데이트됩니다. 실행이 완료된 후에는 ListenableWorker에 진행률을 설정하려는 시도가 무시됩니다.
getWorkInfoBy…() 또는 getWorkInfoBy…LiveData() 메서드 중 하나를 사용하여 진행률 정보를 관찰할 수도 있습니다. 이러한 메서드는 Data를 반환하는 새 getProgress() 메서드가 있는 WorkInfo의 인스턴스를 반환합니다.
업데이트 진행률
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()
}
}
자바
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
}
}
자바
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)
}
}
자바
workManager.getWorkInfoByIdLiveData(syncWorker.id)
.observe(getViewLifecycleOwner(), workInfo -> {
if (workInfo != null) {
int stopReason = workInfo.getStopReason();
logStopReason(syncWorker.id, workInfo.getStopReason());
}
});
Worker 객체의 수명 주기 및 상태에 관한 자세한 내용은 작업 상태를 참고하세요.