В этом уроке задаем критери для запуска задачи.

 


Полный список уроков курса:


 

 

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, Kotlin, RxJava, Dagger, Тестирование 

- ну и если просто хочется поговорить с коллегами по разработке, то есть чат Флудильня

- новый чат Performance для обсуждения проблем производительности и для ваших пожеланий по содержанию курса по этой теме 




Language

Социальные сети

 

Telegram канал



Android чат в Telegram



Группа ВКонтакте



Поддержка проекта

Яндекс
410011180491924

WebMoney
R248743991365
Z551306702056

Paypal