观察工作器的中间进度

WorkManager 2.3.0-alpha01 为设置和观察工作器的中间进度添加了一流支持。如果应用在前台运行时,工作器保持运行状态,也可以使用返回 WorkInfoLiveData 的 API 向用户显示此信息。

ListenableWorker 现在支持 setProgressAsync() API,此类 API 可以保留中间进度。借助这些 API,开发者能够设置可通过界面观察到的中间进度。进度由 Data 类型表示,这是一个可序列化的属性容器(类似于 inputoutput,并且受到相同的限制)。

只有在 ListenableWorker 运行时才能观察到和更新进度信息。如果尝试在 ListenableWorker 完成执行后在其中设置进度,则将会被忽略。您还可以使用 getWorkInfoBy…()getWorkInfoBy…LiveData() 方法来观察进度信息。这两个方法会返回 WorkInfo 的实例,后者有一个返回 Data 的新 getProgress() 方法。

更新进度

对于使用 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 对象的更多文档,请阅读工作状态和观察工作