WorkManager ma wbudowaną obsługę ustawiania i obserwowania postępu pośredniego w przypadku procesów roboczych. Jeśli proces roboczy działał, gdy aplikacja była na
pierwszym planie, te informacje mogą być też wyświetlane użytkownikowi za pomocą interfejsów API, które
zwracają LiveData obiektu
WorkInfo.
ListenableWorker obsługuje teraz interfejs API
setProgressAsync(), który umożliwia utrwalanie postępu pośredniego. Te interfejsy API pozwalają programistom ustawiać postęp pośredni, który może być obserwowany przez interfejs użytkownika.
Postęp jest reprezentowany przez typ Data,
który jest serializowalnym kontenerem właściwości (podobnym do input i
output,
oraz podlegającym tym samym ograniczeniom).
Informacje o postępie można obserwować i aktualizować tylko wtedy, gdy działa ListenableWorker. Próby ustawienia postępu w ListenableWorker po zakończeniu jego działania są ignorowane.
Informacje o postępie
możesz też obserwować za pomocą jednej z metod getWorkInfoBy…() lub
getWorkInfoBy…LiveData(). Te metody zwracają instancje
WorkInfo, która ma nową
getProgress() metodę
zwracającą Data.
Aktualizowanie postępu
W przypadku programistów Java, którzy używają ListenableWorker
lub Worker, interfejs API
setProgressAsync()
zwraca ListenableFuture<Void>. Aktualizowanie postępu jest asynchroniczne,
ponieważ proces aktualizacji obejmuje przechowywanie informacji o postępie w bazie danych.
W Kotlinie możesz użyć CoroutineWorker
obiektu's setProgress()
funkcji rozszerzenia, aby zaktualizować informacje o postępie.
Ten przykład pokazuje ProgressWorker. Gdy Worker się uruchamia, ustawia postęp na 0, a po zakończeniu aktualizuje wartość postępu do 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();
}
}
Obserwowanie postępu
Aby obserwować informacje o postępie, użyj metod getWorkInfoById i uzyskaj odniesienie do
WorkInfo.
Oto przykład, który używa getWorkInfoByIdFlow w Kotlinie i getWorkInfoByIdLiveData w Javie.
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
}
}
});
Obserwowanie stanu przyczyny zatrzymania
Aby sprawdzić, dlaczego Worker został zatrzymany, możesz zarejestrować przyczynę zatrzymania, wywołując
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());
}
});
Więcej informacji o cyklu życia i stanach obiektów Worker znajdziesz w artykule
Stany procesu roboczego.