WorkManager 为设置和观察工作器的中间进度添加了内置支持。如果应用在前台运行时,工作器保持运行状态,那么也可以使用返回 WorkInfo
的 LiveData
的 API 向用户显示此信息。
ListenableWorker
现在支持 setProgressAsync()
API,此类 API 允许保留中间进度。借助这些 API,开发者能够设置可通过界面观察到的中间进度。进度由 Data
类型表示,这是一个可序列化的属性容器(类似于 input
和 output
,并且受到相同的限制)。
只有在 ListenableWorker
运行时才能观察到和更新进度信息。如果尝试在 ListenableWorker
完成执行后在其中设置进度,则将会被忽略。
您还可以使用 getWorkInfoBy…()
或 getWorkInfoBy…LiveData()
方法来观察进度信息。这两个方法会返回 WorkInfo
的实例,后者有一个返回 Data
的新 getProgress()
方法。
更新进度
对于使用 ListenableWorker
或 Worker
的 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();
}
}
观察进度
如需观察进度信息,请使用 getWorkInfoById
方法,并获取对 WorkInfo
的引用。
以下示例分别使用 getWorkInfoByIdFlow
(适用于 Kotlin)和 getWorkInfoByIdLiveData
(适用于 Java)。
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
}
}
});
如需详细了解如何观察 Worker
对象,请阅读工作状态和观察工作。
如需了解如何在工作意外终止时获取 stopReason,请参阅观察停止原因状态。