WorkManager ma wbudowaną obsługę ustawiania i obserwowania pośrednich postępów w przypadku procesów roboczych. Jeśli proces działał, gdy aplikacja była na pierwszym planie, te informacje można też wyświetlić użytkownikowi za pomocą interfejsów API, które zwracają LiveData WorkInfo.
Interfejs ListenableWorker obsługuje teraz interfejs API setProgressAsync(), który umożliwia zachowywanie postępów pośrednich. Te interfejsy API umożliwiają deweloperom ustawianie pośredniego postępu, który może być obserwowany przez interfejs.
Postęp jest reprezentowany przez typ Data, który jest kontenerem właściwości, który można serializować (podobnie jak input i output, i podlega tym samym ograniczeniom).
Informacje o postępach można obserwować i aktualizować tylko wtedy, gdy urządzenieListenableWorker jest włączone. Próby ustawienia postępu w przypadku ListenableWorker
po zakończeniu jego działania są ignorowane.
Postępy możesz też śledzić za pomocą jednej z metod getWorkInfoBy…() lub getWorkInfoBy…LiveData(). Te metody zwracają instancje WorkInfo, które mają nową metodę getProgress() zwracającą Data.
Postęp aktualizacji
W przypadku programistów Java korzystających z ListenableWorker lub Worker interfejs API setProgressAsync() zwraca ListenableFuture<Void>. Aktualizacja postępu jest asynchroniczna, ponieważ proces aktualizacji obejmuje przechowywanie informacji o postępie w bazie danych.
W Kotlinie możesz użyć funkcji rozszerzenia CoroutineWorker obiektu setProgress(), aby zaktualizować informacje o postępie.
Ten przykład pokazuje ProgressWorker. Worker ustawia swój postęp na 0 % po rozpoczęciu, 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ępów
Aby sprawdzić informacje o postępach, użyj metod getWorkInfoById i uzyskaj odniesienie do WorkInfo.
Oto przykład użycia funkcji getWorkInfoByIdFlow w przypadku Kotlina i getWorkInfoByIdLiveData w przypadku Javy.
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ło zatrzymane, możesz zarejestrować przyczynę zatrzymania, wywołując funkcję
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 zadań.