第二个 Android 11 开发者预览版现已推出,快来测试并分享您的反馈吧

链接工作

简介

您可以使用 WorkManager 创建工作链并为其排队。工作链用于指定多个关联任务并定义这些任务的运行顺序。当您需要以特定的顺序运行多个任务时,这尤其有用。

要创建工作链,您可以使用 WorkManager.beginWith(OneTimeWorkRequest)WorkManager.beginWith(List<OneTimeWorkRequest>),这会返回 WorkContinuation 实例。

然后,可以通过 WorkContinuation 使用 WorkContinuation.then(OneTimeWorkRequest)WorkContinuation.then(List<OneTimeWorkRequest>) 来添加从属 OneTimeWorkRequest

每次调用 WorkContinuation.then(...) 都会返回一个新的 WorkContinuation 实例。如果添加了 OneTimeWorkRequestList,这些请求可能会并行运行。

最后,您可以使用 WorkContinuation.enqueue() 方法为 WorkContinuation 链排队。

让我们看一个示例:某个应用对 3 个不同的图像执行图像滤镜(可能会并行执行),然后将这些图像压缩在一起,再上传它们。

Kotlin

    WorkManager.getInstance(myContext)
        // Candidates to run in parallel
        .beginWith(listOf(filter1, filter2, filter3))
        // Dependent work (only runs after all previous work in chain)
        .then(compress)
        .then(upload)
        // Don't forget to enqueue()
        .enqueue()

    

Java

    WorkManager.getInstance(myContext)
        // Candidates to run in parallel
        .beginWith(Arrays.asList(filter1, filter2, filter3))
        // Dependent work (only runs after all previous work in chain)
        .then(compress)
        .then(upload)
        // Don't forget to enqueue()
        .enqueue();

    

Input Merger

在使用 OneTimeWorkRequest 链时,父级 OneTimeWorkRequest 的输出将作为输入传递给子级。因此在上面的示例中,filter1filter2filter3 的输出将作为输入传递给 compress 请求。

为了管理来自多个父级 OneTimeWorkRequest 的输入,WorkManager 使用 InputMerger

WorkManager 提供两种不同类型的 InputMerger

对于上面的示例,假设我们要保留所有图像滤镜的输出,则应使用 ArrayCreatingInputMerger

Kotlin

    val compress: OneTimeWorkRequest = OneTimeWorkRequestBuilder<CompressWorker>()
        .setInputMerger(ArrayCreatingInputMerger::class)
        .setConstraints(constraints)
        .build()

    

Java

    OneTimeWorkRequest compress =
        new OneTimeWorkRequest.Builder(CompressWorker.class)
            .setInputMerger(ArrayCreatingInputMerger.class)
            .setConstraints(constraints)
            .build();

    

链接和工作状态

创建 OneTimeWorkRequest 链时,需要注意以下几点:

  • 从属 OneTimeWorkRequest 仅在其所有父级 OneTimeWorkRequest 都成功完成(即返回 Result.success())时才会被解除阻塞(变为 ENQUEUED 状态)。

  • 如果有任何父级 OneTimeWorkRequest 失败(返回 Result.failure()),则所有从属 OneTimeWorkRequest 也会被标记为 FAILED

  • 如果有任何父级 OneTimeWorkRequest 被取消,则所有从属 OneTimeWorkRequest 也会被标记为 CANCELLED

要了解详情,请参阅取消和停止工作