15 ноября 2015 г.

Оптимизации Doze и App Standby

    Эта запись - неточный перевод статьи Google https://developer.android.com/training/monitoring-device-state/doze-standby.html. Обо всех найденных ошибках смело сообщайте - мне важно улучшить качество своих переводов.
    Начиная с Android 6.0 (API level 23), в Android добавлены две энергосберегающие технологии, которые увеличивают время жизни батареи, путём управление поведением приложений, когда устройство не подключено к источнику питания. Doze уменьшает потребление батареи откладыванием фоновых активностей приложений, использующих процессор и сеть, когда устройство не используется долгий период времени. App Standby откладывает использование процессора и сети приложениями, с которыми пользователь долго не взаимодействовал.
    Doze и App Standby управляют поведением всех приложений, работающих в Android 6.0 и выше, вне зависимости от того, используется TagetSdkVersion 23 или нет. Для обеспечения удобства взаимодействия пользователя с вашим приложением, протестируйте его в режимах Doze и App Standby и внесите необходимые корректировки в его код. Вся дополнительная информация под катом.

Понимание Doze

    Если пользователь оставляет устройство не подключенным, с отключенным экраном, на некоторое время, устройство входит в режим Doze. В режиме Doze система пытается сохранить заряд батареи, ограничивая приложениям доступ к сети и сервисам, нагружающим процессор. Откладываются задачи (Примечание: имеются в виду jobs, в контексте JobScheduler), синхронизации, алармы (Примечание: имеются в виду alarms, в контексте AlarmManager).
    Периодически система выходит из Doze на короткий промежуток времени, позволяя приложениям завершить отложенные активности. В этом окне обслуживания (в оригинале: maintenance window) система запускает все отложенные синхронизации, задачи и алармы; даёт приложениям доступ к сети.
Схема режима DozeРис. 1. Doze предоставляет приложениям повторяющееся окно обслуживания с доступом к сети и отслеживает их отложенные активности. Кликабельно
    По завершению каждого из окон обслуживания система вновь входит в режим Doze, останавливая сетевые активности и откладывая задачи, алармы и синхронизации. С течением времени система планирует окна обслуживания всё реже и реже, помогая снизить расход заряда батареи, особенно в ситуациях, когда устройство давно зарядили и не использовали.
    Как только пользователь пробуждает устройство, перемещая его, или включает экран, или ставит на зарядку, система выходит из Doze и все приложения возвращаются к обычной активности.

Ограничения Doze

    Режим Doze накладывает следующие ограничения на приложения:
  • Останавливается подключение к сети
  • Система игнорирует вейк локи (wake lock)
  • Стандартные алармы, установленные через AlarmManager (включая setExact() и setWindow()) откладываются до ближайшего окна обслуживания
    • Если вам необходимо установить аларм для запуска в Doze, используйте setAndAllowWhileIdle() или setExactAndAllowWhileIdle()
    • setAlarmClock() продолжает запускаться как обычно - при кратком выходе системы из Doze
  • Система не ищет Wi-Fi сети
  • Система не позволяет запускаться синк адаптерам
  • Система не позволяет запускаться джоб шедулерам

Адаптирование приложения для Doze

    Doze затронет ваши приложения с разной степенью ущерба, в зависимости от того, какие сервисы и как часто они используют. Многие функции приложений будут работать нормально между циклами Doze безо всяких модификаций. В некоторых случаях вам нужно оптимизировать использование задач, алармов и синхронизаций. Приложения должны разумно управлять своими активностями в окнах обслуживания.
    Doze однозначно затронет активности, управляемые через AlarmManager, потому что алармы для Android 5.1 (API level 22) и ниже не запустятся, когда система в режиме Doze.
    Чтобы помочь с планированием алармов, в Android 6.0 (API level 23) добавлены два новых метода AlarmManager:setAndAllowWhileIdle() и setExactAndAllowWhileIdle(). С этими методами вы можете установить алармы, которые сработают, когда система в Doze.
Замечание. Ни setAndAllowWhileIdle(), ни setExactAndAllowWhileIdle() не могут запускать алармы чаще, чем раз в 15 мину на приложение.
    Doze ограничивает доступ к сети и это может быть чревато для вашего приложения, особенно если приложение реагирует на сообщения, приходящие в реальном времени. Если вашему приложению нужно постоянное подключение к сети для получения сообщений, вы должны стараться использовать Google Cloud Messaging (GCM).
    Чтобы убедиться, что поведение вашего приложения в Doze такое, как и ожидается, вы можете принудительно войти в Doze и выйти из него с помощью команд adb. Для информации смотрите раздел тестирование с Doze и App Standby ниже по тексту.

Понимание App Standby

    App Standby позволяет системе определять, что приложение ничего не делает, когда пользователь не взаимодействует с ним. Система делает эти выводы в случае, когда пользователь не работает с приложением некоторый период времени и ни одно из следующих условий не выполняется:
  • Пользователь явно, своими руками, запускает приложение
  • Приложение имеет процесс, в данный момент находящийся на переднем плане (это может быть его активити или форэграунд сервис (специальный вид сервиса, требующий иконку в области уведомлений; пример — музыкальный плеер), или же другое приложение использует его активити или форэграунд сервис)
  • Приложение создаёт уведомления, которые пользователь видит на экране блокировки или в области уведомлений
    Когда пользователь ставит устройство на зарядку, система выводит приложение из состояния "анабиоза" и позволяет ему свободно получить доступ к сети и выполнить любые отложенные задачи и синхронизации. Если устройство в простое уже долгое время, система позволяет бездействующим приложениям получать доступ к сети около одного раза в день.

Использование GCM для взаимодействия с вашим приложением, пока устройство простаивает

    Google Cloud Messaging (GCM) - это сервис типа облако-устройство, который позволяет вам в реальном времени отправлять сообщения от сервера к приложению на устройстве. GCM предоставляет единое стойкое подключение к облаку; все приложения, которым нужно получать сообщения в реальном времени, могут подсесть на это подключение. Оно имеет множество технологий оптимизации расхода заряда батареи, а возможность использовать его разными приложениям сводит на нет необходимость создавать своё собственное постоянное подключение для каждого из них. По этой причине, если вашему приложению необходимо получать сообщение от бэкэнд сервиса, мы настоятельно рекомендуем использовать GCM, вместо поднятия собственного постоянного подключения.
    GCM оптимизирован для работы с Doze и App Standby режимами посредством высокоприоритетных GCM сообщений. Высокоприоритетные GCM сообщения позволяют вам пробуждать ваше приложение и давать ему доступ к сетевому подключению, даже если устройство находится в режиме Doze или приложение подавляется режимом App Standby. В режимах Doze и App Standby система доставляет сообщение приложению, даёт ему временный доступ к сети и позволяет использовать частичные вейк локи (Примечание: новый, появился в API level 23, режим вейк локов; разрешает продолжать использовать CPU до тех пор, пока вейк лок не будет снят), после чего возвращает устройство или приложение в состояние простоя.
    Высокоприоритетные GCM сообщения никак иначе не меняют работу Doze и не задевают состояние других приложений. Это означает, что ваше приложение может использовать их для эффективной связи, в то время как разряд батареи системой и другими приложениями сводится к минимуму.
    Если ваше приложение нуждается в получении сообщений от бэкэнд сервиса, то главный бест практик здесь - использование GCM. Если ваши сервер и клиент уже используют GCM, убедитесь, что сервер использует высокоприоритетные сообщения для критичных сообщений, т.к. только они гарантированно будут доставлены, когда устройство находится в режиме Doze.

Поддержка других сценариев использования

    Практически все приложения должны без проблем работать с Doze и подчиняться управлению сетевыми подключениями, алармами, задачами и синхронизациями, а также использовать высокоприоритетные GCM сообщения. Но есть узкий набор ситуаций, когда нормальная работа в Doze невозможна. Для таких ситуаций система предоставляет управляемый белый список приложений, которые частично освобождаются от оптимизаций Doze и App Stanby.
    Приложение из белого списка в режимах Doze и App Standby может использовать сеть и удерживать частичные вейк локи. Как бы то ни было, все прочие ограничения распространяются в том числе на приложения из белого списка. Например, задачи и синхронизации для приложений из белого списка откладываются, обычные алармы AlarmManager'а не выполняются. Приложение может проверить, находится ли оно сейчас в белом списке, вызовом isIgnoringBatteryOptimizations().
    Пользователи могут вручную управлять белым списком в Settings > Battery > Battery Optimization. Кроме того, система предоставляет способы запросить у пользователя добавление приложения в белый список.
  • Приложение может использовать интент ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS для переноса пользователя напрямую в Battery Optimization, где пользователь сможет добавить приложение в список исключений
  • Использование пермишена REQUEST_IGNORE_BATTERY_OPTIMIZATIONS даёт возможность вызвать системный запрос, позволяющий добавить приложение напрямую в белый список, без путешествия по настройкам. Для поднятия диалога приложение должно использовать интент ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS
  • Пользовать может вручную удалить приложение из белого списка, если посчитает необходимым
    Прежде чем просить пользователя добавить приложение в белый список, убедитесь, что это реально необходимо (см. таблицу внизу).
Важное замечание. Правила Google Play запрещают приложениям запрашивать исключение из управления питанием в Android 6.0+ (Doze и App Standby), кроме случаев, когда нарушается их ключевая функциональность.

Тестирование с Doze и App Standby

    Чтобы пользователю было комфортно работать с вашим приложением, вам нужно полноценно тестировать его в Doze и App Standby.

Тестирование вашего приложения в Doze

    Для проверки приложения в режиме Doze:
  1. Прошейте на устройство или запустите эмулятор с Android 6.0 (API level 23)
  2. Подключите устройство к компьютеру и установите приложение
  3. Запустите приложение и оставьте его активным
  4. Выключите экран устройства (приложение остаётся активным)
  5. Форсируйте переход в Doze выполнением следующих команд:
    • $ adb shell dumpsys battery unplug
    • $ adb shell dumpsys deviceidle step

      Вам может потребоваться выполнить вторую команду более одного раза. Повторяйте её, пока состояние устройства не изменится на бездействие.
  6. Наблюдайте за поведением приложения после того, как устройство вновь будет активно. Убедитесь, что приложение нормально (Примечание: дословно в тексте написано "элегантно". Предполагаю, что имеется в виду, что оно не только не крашит, но и нет ANR'ов) восстанавливает работу, когда устройство выходит из режима Doze.

Тестирование вашего приложения с App Standby

    Для проверки приложения в режиме App Standby:
  1. Прошейте на устройство или запустите эмулятор с Android 6.0 (API level 23)
  2. Подключите устройство к компьютеру и установите приложение
  3. Запустите приложение и оставьте его активным
  4. Форсируйте переход в App Standby выполнением команд:
    • $ adb shell dumpsys battery unplug
    • $ adb shell am set-inactive <packageName> true
  5. Симулируйте просыпание приложения выполнением команд:
    • $ adb shell am set-inactive <packageName> false
    • $ adb shell am get-inactive <packageName>
  6. Наблюдайте за поведением приложения при его просыпании. Убедитесь, что приложение нормально восстанавливает работу при выходе из режима App Standby. Дополнительно нужно проверить, что уведомления приложения и фоновые задачи продолжают работать как положено.

Примеры пользовательских сценариев для белого списка

    В таблице ниже выделены те пользовательские сценарии, в которых дозволено запрашивать добавление в белый список, для отключения технологий оптимизации батареи. В основном, приложение не должно проситься в белый список, кроме случаев, когда нарушается их ключевая функциональность или имеются технические ограничения, делающими невозможным использование высокоприоритетных GCM сообщений.
    Для дополнительной информации читайте выше раздел "Поддержка других сценариев использования".
Тип Сценарии Можно использовать GCM? Приемлем белый список? Замечания
Чат или приложение для звонков Требуется доставлять сообщения в реальном времени, пока устройство в Doze или приложение в App Standby Да, используется GCM Не приемлемо Нужно использовать высокоприоритетные GCM сообщения для пробуждения приложения и получения доступа к сети
Да, но не используются высокоприоритетные GCM сообщения
Чат или приложение для звонков;
Корпоративные приложения VOIP
Нет, невозможно использовать GCM, потому что существуют технические зависимости от других сервисов сообщений или Doze и App Standby ломают ключевую функциональность приложения Приемлемо


Комментариев нет:

Отправить комментарий