高级WorkManager主题

WorkManager可以轻松设置和安排精心设计的任务请求。您可以将API用于以下场景:

  • 以指定顺序运行的链式任务序列
  • 唯一的命名序列,包含应用程序启动两个具有相同名称的序列时会发生什么的规则
  • 该任务传递和返回值,包括在每个任务参数传递给下一个任务链中的链接任务

链式任务

您的应用可能需要按特定顺序运行多个任务。 WorkManager允许您创建和排队指定多个任务的工作序列,以及它们应运行的顺序。

例如,假设您的应用程序有三个 OneTimeWorkRequest对象:workAworkB,和 workC。任务必须按该顺序运行。要将它们排入队列,请使用该WorkManager.beginWith(OneTimeWorkRequest) 方法创建一个序列 ,并传递第一个OneTimeWorkRequest对象; 该方法返回一个WorkContinuation对象,该对象定义了一系列任务。然后OneTimeWorkRequest按顺序添加剩余的对象, WorkContinuation.then(OneTimeWorkRequest)最后将整个序列排入队列 WorkContinuation.enqueue()

WorkManager.getInstance()
    .beginWith(workA)
        // Note: WorkManager.beginWith() returns a
        // WorkContinuation object; the following calls are
        // to WorkContinuation methods
    .then(workB)    // FYI, then() returns a new WorkContinuation instance
    .then(workC)
    .enqueue();

WorkManager运行中所要求的顺序执行这些任务,根据每个任务的指定的约束。如果任何任务返回Result.failure(),则整个序列结束。

您还可以将多个OneTimeWorkRequest 对象传递给任何 beginWith(List<OneTimeWorkRequest>)then(List<OneTimeWorkRequest>)调用。如果将多个OneTimeWorkRequest对象传递给单个方法调用,则在WorkManager运行序列的其余部分之前运行所有这些任务(并行)。例如:

WorkManager.getInstance()
    // First, run all the A tasks (in parallel):
    .beginWith(Arrays.asList(workA1, workA2, workA3))
    // ...when all A tasks are finished, run the single B task:
    .then(workB)
    // ...then run the C tasks (in any order):
    .then(Arrays.asList(workC1, workC2))
    .enqueue();

您可以通过使用WorkContinuation.combine(List<OneTimeWorkRequest>)方法连接多个链来创建更复杂的序列。例如,假设您要运行如下序列:

图1.您可以使用 WorkContinuation 设置复杂的链式任务。

要设置此序列,请创建两个单独的链,然后将它们连接到第三个链中:

WorkContinuation chain1 = WorkManager.getInstance()
    .beginWith(workA)
    .then(workB);
WorkContinuation chain2 = WorkManager.getInstance()
    .beginWith(workC)
    .then(workD);
WorkContinuation chain3 = WorkContinuation
    .combine(Arrays.asList(chain1, chain2))
    .then(workE);
chain3.enqueue();

高级WorkManager主题

WorkManager可以轻松设置和安排精心设计的任务请求。您可以将API用于以下场景:

  • 以指定顺序运行的链式任务序列
  • 唯一的命名序列,包含应用程序启动两个具有相同名称的序列时会发生什么的规则
  • 该任务传递和返回值,包括在每个任务参数传递给下一个任务链中的链接任务

链式任务

您的应用可能需要按特定顺序运行多个任务。 WorkManager允许您创建和排队指定多个任务的工作序列,以及它们应运行的顺序。

例如,假设您的应用程序有三个 OneTimeWorkRequest对象:workAworkB,和 workC。任务必须按该顺序运行。要将它们排入队列,请使用该WorkManager.beginWith(OneTimeWorkRequest) 方法创建一个序列 ,并传递第一个OneTimeWorkRequest对象; 该方法返回一个WorkContinuation对象,该对象定义了一系列任务。然后OneTimeWorkRequest按顺序添加剩余的对象, WorkContinuation.then(OneTimeWorkRequest)最后将整个序列排入队列 WorkContinuation.enqueue()

 

科特林

JAVA的

 



 

WorkManager.getInstance()
    .beginWith(workA)
        // Note: WorkManager.beginWith() returns a
        // WorkContinuation object; the following calls are
        // to WorkContinuation methods
    .then(workB)    // FYI, then() returns a new WorkContinuation instance
    .then(workC)
    .enqueue();

 

 

WorkManager运行中所要求的顺序执行这些任务,根据每个任务的指定的约束。如果任何任务返回Result.failure(),则整个序列结束。

您还可以将多个OneTimeWorkRequest 对象传递给任何 beginWith(List<OneTimeWorkRequest>)then(List<OneTimeWorkRequest>)调用。如果将多个OneTimeWorkRequest对象传递给单个方法调用,则在WorkManager运行序列的其余部分之前运行所有这些任务(并行)。例如:

 

科特林

JAVA的

 



 

WorkManager.getInstance()
    // First, run all the A tasks (in parallel):
    .beginWith(Arrays.asList(workA1, workA2, workA3))
    // ...when all A tasks are finished, run the single B task:
    .then(workB)
    // ...then run the C tasks (in any order):
    .then(Arrays.asList(workC1, workC2))
    .enqueue();

 

 

您可以通过使用WorkContinuation.combine(List<OneTimeWorkRequest>)方法连接多个链来创建更复杂的序列。例如,假设您要运行如下序列:

图1.您可以使用 WorkContinuation 设置复杂的链式任务。

要设置此序列,请创建两个单独的链,然后将它们连接到第三个链中:



 

WorkContinuation chain1 = WorkManager.getInstance()
    .beginWith(workA)
    .then(workB);
WorkContinuation chain2 = WorkManager.getInstance()
    .beginWith(workC)
    .then(workD);
WorkContinuation chain3 = WorkContinuation
    .combine(Arrays.asList(chain1, chain2))
    .then(workE);
chain3.enqueue();

在这种情况下,之前WorkManager运行。它之前也运行过。后两者与已经完成, 运行。workAworkBworkCworkDworkBworkDWorkManagerworkE

注意:虽然WorkManager按顺序运行每个子链,但无法保证任务chain1可能与其中的任务重叠chain2。例如,workB可能在之前或之后运行workC,或者它们可能同时运行。唯一的承诺是每个子链中的任务将按顺序运行; 也就是说,workB直到workA 完成后才开始。

这些方法有许多变体WorkContinuation 可以为特定情况提供缩写。有关详细信息,请参阅 WorkContinuation参考。

独特的工作顺序

您可以通过调用 而不是开始序列 来创建唯一的工作序列。每个独特的工作序列都有一个名称; 在只允许使用该名称一次一个工作序列。创建新的唯一工作序列时,如果已存在具有相同名称的未完成序列,则指定应执行的操作:beginUniqueWork(String, ExistingWorkPolicy, OneTimeWorkRequest)beginWith(OneTimeWorkRequest)WorkManagerWorkManager

  • 取消现有序列并使用新序列 替换
  • 保持现有序列并忽略您的新请求
  • 将新序列附加到现有序列,在现有序列的最后一个任务完成后运行新序列的第一个任务

如果您的任务不应多次排队,则唯一的工作顺序非常有用。例如,如果您的应用需要将其数据同步到网络,您可以将名为“sync”的序列排队,并指定如果已经有一个具有该名称的序列,则应忽略您的新任务。如果您需要逐步建立一长串任务,那么独特的工作顺序也很有用。例如,照片编辑应用程序可能允许用户撤消一长串操作。每个撤消操作可能需要一段时间,但必须以正确的顺序执行。在这种情况下,应用程序可以创建“撤消”链并根据需要将每个撤消操作附加到链。

输入参数和返回值

为了获得更大的灵活性,您可以将参数传递给任务并让任务返回结果。传递和返回的值是键值对。要将参数传递给任务,请在WorkRequest.Builder.setInputData(Data) 创建WorkRequest 对象之前调用该 方法。该方法采用Data您创建的对象 Data.Builder。本Worker类可以通过调用访问这些参数 Worker.getInputData()。要输出返回值,任务应将其包括在内Result(例如,返回 Result.success(Data)。您可以通过观察任务获得输出WorkInfo

例如,假设您有一个Worker执行耗时计算的类。以下代码显示了Worker 该类的外观:

// Define the Worker class:
public class MathWorker extends Worker {

    // Define the parameter keys:
    public static final String KEY_X_ARG = "X";
    public static final String KEY_Y_ARG = "Y";
    public static final String KEY_Z_ARG = "Z";
    // ...and the result key:
    public static final String KEY_RESULT = "result";

    public MathWorker(
        @NonNull Context context,
        @NonNull WorkerParameters params) {
        super(context, params);
    }

    @Override
    public Result doWork() {
        // Fetch the arguments (and specify default values):
        int x = getInputData().getInt(KEY_X_ARG, 0);
        int y = getInputData().getInt(KEY_Y_ARG, 0);
        int z = getInputData().getInt(KEY_Z_ARG, 0);

        // ...do the math...
        int result = myCrazyMathFunction(x, y, z);

        //...set the output, and we're done!
        Data output = new Data.Builder()
            .putInt(KEY_RESULT, result)
            .build();
        return Result.success(output);
    }
}

要创建工作并传递参数,您可以使用如下代码:

// Create the Data object:
Data myData = new Data.Builder()
    // We need to pass three integers: X, Y, and Z
    .putInt(KEY_X_ARG, 42)
    .putInt(KEY_Y_ARG, 421)
    .putInt(KEY_Z_ARG, 8675309)
    // ... and build the actual Data object:
    .build();

// ...then create and enqueue a OneTimeWorkRequest that uses those arguments
OneTimeWorkRequest mathWork = new OneTimeWorkRequest.Builder(MathWorker.class)
        .setInputData(myData)
        .build();
WorkManager.getInstance().enqueue(mathWork);

返回的值将在任务中可用WorkInfo

WorkManager.getInstance().getWorkInfoByIdLiveData(mathWork.getId())
    .observe(lifecycleOwner, info -> {
         if (info != null && info.getState().isFinished()) {
           int myResult = info.getOutputData().getInt(KEY_RESULT,
                  myDefaultValue));
           // ... do something with the result ...
         }
    });

如果链接任务,则一个任务的输出可用作链中下一个任务的输入。如果它是一个简单的链,只有一个OneTimeWorkRequest后跟另一个 OneTimeWorkRequest,第一个任务通过调用返回其结果Result.success(Data),下一个任务通过调用获取该结果 getInputData()。如果链更复杂 - 例如,因为几个任务都将输出发送到单个后续任务 - 您可以定义一个InputMerger on OneTimeWorkRequest.Builder来指定如果不同任务返回具有相同键的输出会发生什么。

其他资源

WorkManager是一个Android Jetpack架构组件。在Sunflower 演示应用程序中查看它的使用情况。

 

猜你喜欢

转载自blog.csdn.net/qulonglong110/article/details/85049263
今日推荐