观察中间工作器进度

WorkManager 对工作器中间进度的设置和观察提供了一流的支持。如果工作器在应用处于前台时正在运行,此信息还可以使用返回 WorkInfoLiveData 的 API 向用户显示。

ListenableWorker 现在支持 setProgressAsync() API,该 API 允许它持久化中间进度。这些 API 允许开发者设置可由 UI 观察到的中间进度。进度由 Data 类型表示,它是一个可序列化的属性容器(类似于 inputoutput,并受相同限制)。

进度信息只能在 ListenableWorker 运行时观察和更新。在 ListenableWorker 完成执行后尝试设置进度将被忽略。您还可以通过使用 getWorkInfoBy…()getWorkInfoBy…LiveData() 方法之一来观察进度信息。这些方法返回 WorkInfo 的实例,WorkInfo 有一个新的 getProgress() 方法,该方法返回 Data

更新进度

对于使用 ListenableWorkerWorker 的 Java 开发者,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();
    }
}

观察进度

观察进度信息也很简单。您可以使用 getWorkInfoBy…()getWorkInfoBy…LiveData() 方法,并获取对 WorkInfo 的引用。

以下是使用 getWorkInfoByIdLiveData API 的示例。

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
             }
      }
});

有关观察 Worker 对象的更多文档,请阅读工作状态和观察工作