Obserwuj postęp pośredniej instancji roboczej

Usługa WorkManager zapewnia najwyższej klasy obsługę konfigurowania i obserwowania postępów na etapie pośrednim w instancjach roboczych. Jeśli instancja robocza była uruchomiona, gdy aplikacja działała na pierwszym planie, informacje te mogą być również wyświetlane użytkownikowi za pomocą interfejsów API, które zwracają LiveData wartości WorkInfo.

ListenableWorker obsługuje teraz interfejs API setProgressAsync(), co pozwala zachować postęp pośredni. Te interfejsy API umożliwiają programistom ustawianie pośrednich postępów, które mogą być obserwowane w interfejsie użytkownika. Postęp reprezentuje typ Data, który jest zserializowanym kontenerem usług (podobny do input i output, który podlega tym samym ograniczeniom).

Informacje o postępie można obserwować i aktualizować tylko podczas działania ListenableWorker. Próby ustawienia postępu w elemencie ListenableWorker po jego zakończeniu są ignorowane. Informacje o postępach możesz też obserwować, korzystając z metody getWorkInfoBy…() lub getWorkInfoBy…LiveData(). Te metody zwracają wystąpienia funkcji WorkInfo, która ma nową metodę getProgress() zwracającą wartość Data.

Postęp aktualizacji

W przypadku programistów Java korzystających z ListenableWorker lub Worker interfejs API setProgressAsync() zwraca wartość ListenableFuture<Void>. Aktualizowanie postępu przebiega asynchronicznie, ponieważ proces aktualizacji obejmuje przechowywanie informacji o postępach w bazie danych. Aby zaktualizować informacje o postępie, w Kotlin możesz użyć funkcji rozszerzenia setProgress() obiektu CoroutineWorker.

Ten przykład to prosty element ProgressWorker. Po rozpoczęciu Worker ustawia postęp na 0, a po zakończeniu aktualizuje wartość postępu na 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

Obserwowanie postępów również jest proste. Możesz użyć metody getWorkInfoBy…() lub getWorkInfoBy…LiveData() i uzyskać odwołanie do WorkInfo.

Oto przykład, w którym wykorzystano interfejs API getWorkInfoByIdLiveData.

Kotlin

WorkManager.getInstance(applicationContext)
    // requestId is the WorkRequest id
    .getWorkInfoByIdLiveData(requestId)
    .observe(observer, Observer { 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
             }
      }
});

Więcej dokumentacji na temat obserwacji obiektów Worker znajdziesz w artykule Stany pracy i obserwacja miejsc pracy.