Найти в Дзене

WorkManager. Всегда ли запустится сразу?

Всю прошлую неделю у меня с коллегой был вялотекущий спор на одну тему. Представьте, что у нас есть WorkManager. Мы решили, что он будет работать каждые 12 часов. По каким-то триггерам и после перезагрузки мы его планируем заново с флагом REPLACE. Но что произойдет, если пользователь будет выключать телефон через 10 часов на ночь (никогда не будет активного промежутка в 12 часов)? Значит ли это, что WorkManager никогда не отработает? У меня и у коллеги были противоположные мнения, но никто не собирался отступать. Пришлось проверить. :) Для проверки я взяла https://github.com/Ladgertha/WorkManagers и оставила только запуск ExampleCoroutineWorker по клику на кнопку (она там единственная). В итоге, сразу при клике на кнопку видим в логах, что воркер успешно отработал и что в базе сохранился его ID. Вопрос решен в мою пользу: воркер отработает сразу же, а не через какой-то указанный период (к этому мы еще вернемся). В базе у нас один воркер с id c423193a-71fc-4331-96bf-73e0313139d4. При к

Всю прошлую неделю у меня с коллегой был вялотекущий спор на одну тему. Представьте, что у нас есть WorkManager. Мы решили, что он будет работать каждые 12 часов. По каким-то триггерам и после перезагрузки мы его планируем заново с флагом REPLACE. Но что произойдет, если пользователь будет выключать телефон через 10 часов на ночь (никогда не будет активного промежутка в 12 часов)? Значит ли это, что WorkManager никогда не отработает? У меня и у коллеги были противоположные мнения, но никто не собирался отступать. Пришлось проверить. :)

Для проверки я взяла https://github.com/Ladgertha/WorkManagers и оставила только запуск ExampleCoroutineWorker по клику на кнопку (она там единственная).

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

-2

В базе у нас один воркер с id c423193a-71fc-4331-96bf-73e0313139d4. При клике на кнопку запускается новый воркер и в табличке перезаписывается время запуска и id. REPLACE правильно отрабатывает. Можно прям десяток раз кликнуть и наблюдать как меняются данные.

Выключаем телефон на 20 минут. Включаем. Немного ждём и воркер отрабатывает. Пока что всё хорошо.

Выключаем телефон ещё раз. Через 20 минут включаем. Заходим в приложение и кликаем на кнопку — воркер отрабатывает и в базе заменяется ID. Выглядит, что все правильно и все моменты предусмотрены. Но почему тогда в другом приложении воркер не запускается сразу же, а только через 12 часов? И там воркер никогда не сможет отработать, если телефон будет активен меньше 12 часов.

Сравниваю реализацию и вижу, что разница только в одном: там мы указываем flexInterval явно.

А теперь самое интересное: если добавить flexInterval в тестовый проект, то воркер тоже запустится не сразу.

Идём в исходники: в библиотеке workmanager указано, что если мы не указываем flexInterval, то он ставится равным интервалу для периодического воркера.

Например, у меня воркер должен работать каждые 15 минут, значит flexInterval будет тоже 15 минут, если не указываем явно. В этом случае воркер запускается сразу (если есть такая возможность).

Что будет, если мы укажем flexInterval = 5 минут для воркера, который должен работать каждые 15 минут? Кликаем на кнопочку и ждем. Воркер запустился через 10 минут (период для запуска минус flexInterval).

Пробуем указать 14 минут. Воркер запускается через минуту (15 минут - 14 минут). Если указываем 10 минут, то запустится через 5 минут. Надеюсь, закономерность понятна.

Получается, что наша проблема была в том, что для 12 часов мы указали 5 минут. А это означает, что наш воркер запускается через 11 часов 55 минут, а не моментально. Загадка решена. :)

-3

Дубль статей в телеграмме — https://t.me/android_junior

Мои заметки в телеграмме — https://t.me/android_junior_notes