В этом уроке задаем критери для запуска задачи.
Полный список уроков курса:
- Урок 1. Lifecycle
- Урок 2. LiveData
- Урок 3. LiveData. Дополнительные возможности
- Урок 4. ViewModel
- Урок 5. Room. Основы
- Урок 6. Room. Entity
- Урок 7. Room. Insert, Update, Delete, Transaction
- Урок 8. Room. Query
- Урок 9. Room. RxJava
- Урок 10. Room. Запрос из нескольких таблиц. Relation
- Урок 11. Room. Type converter
- Урок 12. Room. Миграция версий базы данных
- Урок 13. Room. Тестирование
- Урок 14. Paging Library. Основы
- Урок 15. Paging Library. PagedList и DataSource. Placeholders.
- Урок 16. Paging Library. LivePagedListBuilder. BoundaryCallback.
- Урок 17. Paging Library. Виды DataSource
- Урок 18. Android Data Binding. Основы
- Урок 19. Android Data Binding. Код в layout. Доступ к View
- Урок 20. Android Data Binding. Обработка событий
- Урок 21. Android Data Binding. Observable поля. Двусторонний биндинг.
- Урок 22. Android Data Binding. Adapter. Conversion.
- Урок 23. Android Data Binding. Использование с include, ViewStub и RecyclerView.
- Урок 24. Navigation Architecture Component. Введение
- Урок 25. Navigation. Передача данных. Type-safe аргументы.
- Урок 26. Navigation. Параметры навигации
- Урок 27. Navigation. NavigationUI.
- Урок 28. Navigation. Вложенный граф. Global Action. Deep Link.
- Урок 29. WorkManager. Введение
- Урок 30. WorkManager. Критерии запуска задачи.
- Урок 31. WorkManager. Последовательность выполнения задач.
- Урок 32. WorkManager. Передача и получение данных
- Урок 33. Практика. О чем это будет.
- Урок 34. Практика. TodoApp. Список задач.
- Урок 35. Практика. TodoApp. Просмотр задачи
WorkManager позволяет нам задать критерии запуска задачи, например - включенный интернет на девайсе. Когда вы передадите такую задачу в WorkManager.enqueue, то будет выполнена проверка, что есть интернет. Если он есть, то задача запустится. А если его нет, то задача будет висеть в статусе ENQUEUED, пока инет не появится.
Если задача запущена и интернет по каким-то причинам пропал, то задача будет остановлена и снова запланирована (ENQUEUED).
Давайте рассмотрим, какие критерии мы можем задать.
Для примера будем использовать такую задачу.
public class MyWorker extends Worker { static final String TAG = "workmng"; @NonNull @Override public WorkerResult doWork() { Log.d(TAG, "doWork: start"); try { for (int i = 0; i < 10; i++) { TimeUnit.SECONDS.sleep(1); Log.d(TAG, i + ", isStopped " + isStopped()); if (isStopped()) return WorkerResult.FAILURE; } } catch (InterruptedException e) { e.printStackTrace(); } Log.d(TAG, "doWork: end"); return WorkerResult.SUCCESS; } @Override public void onStopped() { super.onStopped(); Log.d(TAG, "onStopped"); } }
Цикл из 10 пауз и логирование статуса isStopped. Если задача была остановлена, то выходим с статусом FAILURE.
Также логируем метод onStopped.
В Activity код для отслеживания статуса задачи:
WorkManager.getInstance() .getStatusById(myWorkRequest.getId()) .observe(this, new Observer<WorkStatus>() { @Override public void onChanged(@Nullable WorkStatus workStatus) { Log.d(TAG, "onChanged: " + workStatus.getState()); } });
setRequiresCharging (boolean requiresCharging)
Критерий: зарядное устройство должно быть подключено.
Код добавления критерия выглядит так:
Constraints constraints = new Constraints.Builder() .setRequiresCharging(true) .build(); OneTimeWorkRequest myWorkRequest = new OneTimeWorkRequest.Builder(MyWorker.class) .setConstraints(constraints) .build(); WorkManager.getInstance().enqueue(myWorkRequest);
В Constraints.Builder включаем критерий setRequiresCharging, создаем объект Constraints и передаем его в OneTimeWorkRequest.Builder в метод setConstraints.
Для теста я запустил задачу при отключенном зарядном устройстве, затем включил зарядку, затем снова выключил зарядку.
Смотрим логи
21:06:40.077 onChanged: ENQUEUED
21:06:57.866 doWork: start
21:06:57.872 onChanged: RUNNING
21:06:58.867 0, isStopped false
21:06:59.868 1, isStopped false
21:07:00.869 2, isStopped false
21:07:01.871 3, isStopped false
21:07:02.266 onStopped
21:07:02.279 onChanged: ENQUEUED
21:07:02.872 4, isStopped true
21:06:40
При запуске задача была поставлена в ожидание, потому что критерии запуска не были выполнены - зарядное устройство не было подключено.
21:06:57
Я подключил зарядное устройство и WorkManager запустил задачу. Она начала выполняться, статус isStopped = false.
21:07:02
Я отключил зарядное устройство. Критерий не выполнен, задача остановлена (onStopped) и снова запланирована (ENQUEUED).
Флаг isStopped теперь равен true, мы это обрабатываем и выходим из цикла.
Обратите внимание, что статус FAILURE нам не пришел. Т.е. при остановке задачи полностью игнорируется ее результат.
На всякий случай напомню, что запланированная задача никак не зависит от приложения. Можно запустить задачу и закрыть приложение. Потом через какое-то время включить зарядник и задача начнет выполняться.
Остальные критерии устанавливаются и ведут себя аналогично, поэтому я уже не буду приводить код, а только кратко опишу.
setRequiresBatteryNotLow (boolean requiresBatteryNotLow)
Критерий: уровень батареи не ниже критического.
Я проверил этот критерий на AVD эмуляторе. Задача начинает выполняться при уровне заряда больше 20, а останавливается при меньше 16.
setRequiredNetworkType (NetworkType networkType)
Критерий: наличие интернет.
Мы можем указать, какой именно тип сети интернет (NetworkType) должен быть при запуске задачи:
CONNECTED - WiFi или Mobile Data
UNMETERD - только WiFi
METERED - только Mobile Data
NOT_ROAMING - интернет должен быть не роуминговый
NOT_REQUIRED - интернет не нужен
setRequiresDeviceIdle (boolean requiresDeviceIdle)
Критерий: девайс не используется какое-то время и ушел в спячку. Работает на API 23 и выше.
setRequiresStorageNotLow (boolean requiresStorageNotLow)
Критерий: на девайсе должно быть свободное место, не меньше критического порога. Не придумал, как это можно быстро протестить, поэтому не могу подсказать сколько это в мегабайтах.
addContentUriTrigger (Uri uri, boolean triggerForDescendants)
Критерий: задача запустится, когда обновится содержимое указанного Uri. Что означает флаг triggerForDescendants - я пока не знаю. Как только выясню, напишу. Работает на API 24 и выше.
Для одной задачи можно задавать сразу несколько критериев.
Присоединяйтесь к нам в Telegram:
- в канале StartAndroid публикуются ссылки на новые статьи с сайта startandroid.ru и интересные материалы с хабра, medium.com и т.п.
- в чатах решаем возникающие вопросы и проблемы по различным темам: Android, Compose, Kotlin, RxJava, Dagger, Тестирование, Performance
- ну и если просто хочется поговорить с коллегами по разработке, то есть чат Флудильня