WorkManager beginUniqueWork не работает должным образом

В настоящее время я использую WorkManager 1.0.0-alpha02.

def work_version = "1.0.0-alpha02"
implementation "android.arch.work:work-runtime:$work_version" // use -ktx for Kotlin
// optional - Firebase JobDispatcher support
implementation "android.arch.work:work-firebase:$work_version"

У меня нет проблем с запуском фонового рабочего, используя следующий код, когда приложение закрывается.

Используйте enqueue, работайте как ожидалось

OneTimeWorkRequest oneTimeWorkRequest =
        new OneTimeWorkRequest.Builder(SyncWorker.class)
                .addTag(SyncWorker.TAG)
                .build();

WorkManager workManager = WorkManager.getInstance();

workManager.enqueue(oneTimeWorkRequest);

Поскольку я бы хотел, чтобы одновременно выполнялось не более одного SyncWorker. Я пытаюсь использовать

Используйте beginUniqueWork, не работает

OneTimeWorkRequest oneTimeWorkRequest =
        new OneTimeWorkRequest.Builder(SyncWorker.class)
                .addTag(SyncWorker.TAG)
                .build();

WorkManager workManager = WorkManager.getInstance();

workManager.beginUniqueWork(
        SyncWorker.TAG,
        ExistingWorkPolicy.REPLACE,
        oneTimeWorkRequest
);

SyncWorker вообще не работает.

Могу ли я узнать, какой шаг я пропустил? Спасибо.


person Cheok Yan Cheng    schedule 02.06.2018    source источник


Ответы (2)


beginUniqueWork() возвращает WorkContinuation объект. Вам нужно вызвать enqueue для этого WorkContinuation, чтобы фактически поставить его в очередь с помощью WorkManager:

workManager.beginUniqueWork(
    SyncWorker.TAG,
    ExistingWorkPolicy.REPLACE,
    oneTimeWorkRequest
).enqueue();
person ianhanniballake    schedule 02.06.2018
comment
Спасибо. Теперь мне удается заставить его работать. Я тестирую, используя ExistingWorkPolicy.KEEP, и намеренно заставляю рабочего выполнять бесконечный цикл во время сна. Работает не более 1 рабочего. Однако, если я явно выполняю cancelAllWorkByTag(SyncWorker.TAG) и cancelUniqueWork(SyncWorker.TAG) перед второй постановкой в ​​очередь, я замечаю, что предыдущий рабочий не будет убит. Тем не менее, 2-й рабочий может работать. Это заставляет 2 рабочих работать одновременно. Означает ли это, что если мы используем beginUniqueWork, мы не должны вызывать cancelAllWorkByTag и cancelUniqueWork? - person Cheok Yan Cheng; 02.06.2018
comment
Согласно документации отмена это лучшее усилие. Это в равной степени относится ко всем видам Работ. - person ianhanniballake; 02.06.2018
comment
В порядке. Спасибо. Сначала я думал, что если операция отмены не увенчалась успехом, beginUniqueWork не запустит другой воркер. Похоже, мое предположение неверно. - person Cheok Yan Cheng; 02.06.2018
comment
В alpha03 должны быть добавлены дополнительные API, связанные с отменой. Вашему работнику все равно нужно будет проверить отмену, но он сможет досрочно завершить свою работу в случае отмены. - person ianhanniballake; 02.06.2018
comment
Спасибо. Вы знаете, когда выйдет 1.0 версия? Как, мы планируем выпустить некоторый код в продакшн на основе WorkManager. Было бы неплохо узнать, когда будет готова 1.0. - person Cheok Yan Cheng; 03.06.2018
comment
Уже есть ряд приложений, в которых WorkManager запущен в производство. Альфа для компонентов архитектуры больше касается стабильности API, чем стабильности времени выполнения, но YMMV, тщательное тестирование и т. Д. - person ianhanniballake; 03.06.2018
comment
Кстати, чтобы действительно гарантировать, что работает только один Worker, можно ли использовать дополнительную синхронизацию? - gist.github.com/yccheok/b165c483788b09830b3b28148ab7d4c0 - person Cheok Yan Cheng; 03.06.2018
comment
Кажется разумным - person ianhanniballake; 03.06.2018

Ответ от @ianhanniballake, конечно, полезен и верен, но я подумал, что хочу указать, что (с быстро развивающимся API) существует новый метод enqueueUniqueWork(), поэтому я предполагаю, что OP теперь может использовать:

workManager.enqueueUniqueWork(
    SyncWorker.TAG,
    ExistingWorkPolicy.REPLACE,
    oneTimeWorkRequest
);
person drmrbrewer    schedule 17.12.2018
comment
У меня есть похожий код, но мой Worker не вызывается, почему это должно быть? - person Andrey; 04.09.2019