android WorkManager -如何按顺序执行作业

axkjgtzd  于 2023-01-15  发布在  Android
关注(0)|答案(3)|浏览(236)

我有一个服务监听传入的FCM通知。当收到这样的通知时,我用WorkManager运行一个作业。
当同时收到多个通知时,如何确保一次只执行一个作业?作业应该按顺序执行。在这种情况下,我想发送短信,这些不能同时发送。(请注意,我做其他的东西,如http请求在这个工作之前和之后发送短信,这就是为什么我决定为它创建一个作业,而不是直接从该服务发送短信。)

public class MyFirebaseMessagingService extends FirebaseMessagingService {
    public void onMessageReceived(RemoteMessage remoteMessage) {
        //...
        OneTimeWorkRequest sendSmsWorker = new OneTimeWorkRequest.Builder(SendSmsWorker.class).build();
        WorkManager.getInstance().enqueue(sendSmsWorker);
        //...
    }
}

我已经检查了WorkManager文档中的高级部分;它提到了链式序列,但是这些序列必须彼此显式链接(beginWith/then/then/...)。

zfciruhq

zfciruhq1#

您需要将作业创建为具有相同组名的OneTimeWorkRequest,并使用APPEND将它们作为唯一的作业入队。这将使所有作业都附加到同一个链中并按顺序执行。
请注意,您最多应始终返回Result.SUCCESS或Result.RETRY。返回Result.FAILURE将取消所有排队的作业。如果您需要知道作业是否失败,则可以在工作进程setOutputData中设置自定义标志,以根据需要处理此类情况。

final String JOB_GROUP_NAME = "your_jobs_group_name";

......

OneTimeWorkRequest request = new OneTimeWorkRequest.Builder(YOUR_WORK.class)
    .setInputData(YOUR_WORK_DATA_BUILDER.build())
    .build();

final WorkManager workManager = WorkManager.getInstance();
WorkContinuation work = workManager.beginUniqueWork(JOB_GROUP_NAME, ExistingWorkPolicy.APPEND, request);
work.enqueue();
1cosmwyk

1cosmwyk2#

Work Manager中有一个概念,即chaining,我们可以根据需要为工人安排任意多的订单。
假设有一些连续的任务我们必须
1.创建一些数据
1.缓存数据
1.上传数据
现在,为了实现这一点,我们可以按此顺序链接它们,以便它们按顺序运行

WorkManager.getInstance(myContext)
   .beginWith(createDataWork) //This is going enqueue first
   .then(cacheWork)  // enqueue after returning success from create worker
   .then(uploadWork)// enqueue after returning success from cache worker
   .enqueue()

每个then将返回一个new WorkerContinuation()示例

ffx8fchx

ffx8fchx3#

如果返回的结果不是Result.SUCCESS,那么顺序执行Workers而不受中断链的限制的另一种方法是扩展ListenableWorker而不是Worker
如果您看到Workerimplementation,则它们正在使用WorkManager的后台执行器运行所有Worker示例。您可以定义自己的执行器,该执行器使用单个线程:

// Define your executor here
private static final Executor sExecutor = Executors.newSingleThreadExecutor();

@Override
    public final @NonNull ListenableFuture<Result> startWork() {
        mFuture = SettableFuture.create();
        sSerialExecutor.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    Result result = doWork();
                    mFuture.set(result);
                } catch (Throwable throwable) {
                    mFuture.setException(throwable);
                }

            }
        });
        return mFuture;
    }

注意,您必须使用Guava的SettableFuture

相关问题