观察中间工作进程

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

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

只有在 ListenableWorker 运行时才能观察和更新进度信息。尝试在 ListenableWorker 完成其执行后设置进度会被忽略。您还可以使用 getWorkInfoBy…()getWorkInfoBy…LiveData() 方法之一观察进度信息。这些方法返回 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 对象的更多文档,请阅读 工作状态和观察工作