Планирование повторяющихся событий - Handler.PostDelayed и Doze
контекст
Я работаю над приложением фильтра экрана (например, f.lux) для Android. В настоящее время я работаю над функцией постепенного исчезновения фильтра при заходе солнца. Состояние не имеет значения, когда экран выключен, но когда экран включен, важно, чтобы прогресс затухания был правильным (или немедленно обновлялся).
Технические требования
- Я хочу запустить серию намерений с регулярными интервалами.
- Когда экран выключен, их можно игнорировать / исключать, кроме:
- когда экран включается, самое последнее намерение должно быть запущено немедленно.
- Я не хочу разряжать батарею без необходимости.
Очевидные решения и почему они не работают
- Я мог бы использовать
AlarmManager.setInexactRepeating
который, предположительно, является самым энергоэффективным из сигнализаций, кроме:
Первый триггер вашего будильника не будет раньше запрошенного времени, но он может не срабатывать в течение почти полного интервала после этого времени.
Я думаю, это подразумевает, что первый триггер обязательно произойдет в течение первого интервала, то есть устройство разбудит, что приведет к ненужной разрядке батареи.
- Я мог бы использовать
AlarmManager.set
запланировать первый сигнал тревоги. Когда он отключится, я смогу обновить экран, а затем запланировать следующий сигнал тревоги. Это будет работать, но будет вызывать более старые устройства (без Doze) при каждом сигнале тревоги, а не ждать, пока не включится экран. Он также использует AlarmManger в качестве таймера, который документально рекомендует против:
Для операций синхронизации (тики, тайм-ауты и т. Д.) Проще и намного эффективнее использовать Handler.
Хорошо, итак,
- Я мог бы установить один сигнал тревоги, чтобы запустить
Handler
, который будет периодически обновлять пользовательский интерфейс. Но подождите: это зависит отpostDelayed
, который говорит (выделение мое):
Время, проведенное в глубоком сне, добавит дополнительную задержку к выполнению.
Я думаю, это означает, что, когда устройство выходит из спящего режима, следующее обновление может не произойти в течение целого интервала. Я читаю это правильно? Заставить пользователя подождать минуту или две, прежде чем следующее обновление является нарушителем.
CountDownTimer и ValueAnimator оба используют этот метод в своих реализациях, поэтому, если моя интерпретация Handler верна, они оба отсутствуют.
Я мог бы использовать метод на основе обработчика, а также получать события, когда экран выключен, после чего я отменял бы существующую анимацию, а затем запускал новую. Это выглядит наилучшим решением, но, похоже, должен быть более простой способ сделать это.
Заключение
Есть множество других SO вопросов по этой теме. Каждый и его мать рекомендует использовать Handler, но нет абсолютно никакой информации о том, как он ведет себя, когда устройство переходит в спящий режим, кроме приведенной выше цитаты. Это действительно странно, что (очевидно) никто больше не сталкивался с этой проблемой - я делаю что-то действительно необычное или пропускаю что-то простое?
Кто-нибудь может дать представление о том, как Handler.postDelayed
действительно ведет себя, когда устройство переходит в режим сна, и рекомендуете, что мне следует делать в данном конкретном случае?