WorkManager - как выполнять задания последовательно

У меня есть служба, которая прослушивает входящие уведомления FCM. Когда такое уведомление получено, я запускаю задание с помощью WorkManager.

Когда одновременно поступает несколько уведомлений, как я могу гарантировать, что одновременно выполняется только одно задание? Задания следует выполнять последовательно. В этом случае я хочу отправить смс, и они не могут быть отправлены одновременно. (Обратите внимание, что я делаю другие вещи, такие как http-запросы, в этом задании до и после отправки sms, поэтому я решил создать для него задание вместо отправки sms прямо из службы.)

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 / ...).


person user2923322    schedule 14.10.2018    source источник


Ответы (1)


Вам необходимо создать задания как 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();
person PerracoLabs    schedule 14.10.2018
comment
Примечание: в этом случае вы не сможете остановить одно задание из группы. Если вы не храните где-нибудь UUID этой конкретной работы. - person Andrew; 01.11.2019
comment
Я попытался использовать ExistingWorkPolicy.APPEND, но это работает до определенного момента. Если вам нужно поставить в очередь 27 рабочих, то в какой-то момент они останутся в рабочем состоянии и никогда не закончат работу. Я открыл проблему в системе отслеживания проблем здесь: Issuesetracker.google.com/issues/155370056 - person toobsco42; 30.04.2020
comment
Имея обходной путь - всегда возвращать Result.SUCCESS или Result.RETRY, как отменить текущее задание, не отменяя всю цепочку? - person xatokk; 10.05.2021