Как выявить и оптимизировать случаи использования запрета блокировки

Этот документ поможет вам определить и оптимизировать сценарии использования запрета блокировки в вашем приложении, а также узнать, есть ли запреты блокировки, полученные другими библиотеками или системными API, связанными с этим сценарием использования. Поскольку запреты блокировки относятся к вашему приложению, может быть сложно определить источник проблемного запрета. Неправильное использование API может привести к тому, что ваше приложение будет помечено как чрезмерно использующее запрет блокировки, даже если вы не запрашиваете его явным образом.

В этом документе перечислены некоторые распространенные названия запретов блокировки, которые могут встречаться при использовании инструментов отладки запретов блокировки или в отчетах Android Vitals. Эти имена могут происходить из библиотеки или системного API, а также могут быть обфусцированы. Используя инструменты отладки, вы можете выявить запреты блокировки, которые работают некорректно, а затем найти их названия в этом документе. Это поможет вам определить, какой API может вызывать проблему, и найти рекомендации по оптимизации его использования.

В этом документе описаны распространенные сценарии использования запрета блокировки, приведены названия запретов блокировки, используемые различными API и библиотеками, а также даны рекомендации по оптимизации и сокращению использования запрета блокировки.

AlarmManager

AlarmManager получает запреты блокировки и связывает их с вызывающим приложением. AlarmManager получает запрет блокировки, когда срабатывает будильник, и снимает его, когда завершается выполнение метода onReceive().

Названия запретов блокировки

AlarmManager создает запреты блокировки с названием *alarm*. (Звездочки являются частью названия запрета блокировки, а не подстановочными знаками.)

Рекомендация

Чтобы оптимизировать работу будильника, рекомендуем сделать следующее:

  • Чтобы выбрать тип операции, ознакомьтесь с разделом Выбор типа операции. Если точное время не требуется, используйте неточные будильники. Это позволит системе более гибко планировать задачи и экономить заряд батареи.
  • Учитывайте системные квоты на будильники и разрабатывайте приложение так, чтобы оно их соблюдало.
  • Не выполняйте длительные операции в методе onReceive() и планируйте рабочие потоки, если после срабатывания будильника требуется дополнительная обработка.

Аудио и медиа

API мультимедиа могут запрашивать запрет блокировки при записи или воспроизведении аудио. Запреты блокировки относятся к вызывающему приложению.

Названия запретов блокировки

Media API получают запреты блокировки с различными названиями, которые начинаются с Audio:

  • AudioBitPerfect: используется для воспроизведения аудио без потерь через USB.
  • AudioDirectOut – используется для воспроизведения аудио без потерь на телевизоре или специальном устройстве.
  • AudioDup – используется для воспроизведения уведомлений при подключении через Bluetooth или USB.
  • AudioIn – используется для записи звука в режиме видеокамеры, когда микрофон активен.
  • AudioMix – используется для воспроизведения аудио на обычном устройстве.
  • AudioOffload – используется для длительного воспроизведения музыки в приложениях, поддерживающих этот режим.
  • AudioSpatial – используется для воспроизведения многоканального аудио в фильмах или музыке на устройствах, поддерживающих пространственное звучание.
  • AudioUnknown – используется, если другие варианты не подходят.
  • MmapCapture: используется для записи аудио с низкой задержкой.
  • MmapPlayback – используется для воспроизведения с низкой задержкой, например в играх или профессиональных аудиоприложениях.

Рекомендация

Мы рекомендуем следующее:

  • Не объявляйте названия запретов блокировки, которые начинаются с Audio.
  • Если вы используете API мультимедиа, вам не нужно получать запреты блокировки напрямую. Вы можете положиться на API, которые получат необходимые запреты блокировки за вас.
  • Если вы используете API мультимедиа, завершите сеанс мультимедиа и связанную с ним активную службу, когда они больше не нужны.

Bluetooth

Bluetooth API платформы в основном удерживают запреты блокировки ядра во время выполнения действий Bluetooth, которые не связаны с приложением.

Рекомендация

  • Используйте подключение дополнительных устройств для подключения устройств Bluetooth, чтобы не устанавливать запрет блокировки вручную во время подключения Bluetooth.
  • Ознакомьтесь с руководством по обмену данными в фоновом режиме, чтобы узнать, как настроить обмен данными по Bluetooth в фоновом режиме.
  • Если задержка в передаче данных не влияет на пользователей, обычно достаточно использовать WorkManager. Если запрет блокировки необходим, используйте его только во время работы Bluetooth или обработки данных о действиях.

Датчики устройств

Отслеживать данные датчиков устройства, например количество шагов, данные акселерометра или гироскопа, можно несколькими способами.

На устройствах Wear OS используйте сервисы наблюдения за здоровьем, чтобы получать данные о высоте, пульсе и пройденном расстоянии.

Если данные собираются другими приложениями, вы можете использовать Здоровье и спорт в сочетании с WorkManager, чтобы периодически получать данные.

Для отслеживания дельты шагов или пройденного расстояния вы можете использовать Recording API на мобильных устройствах в сочетании с WorkManager для периодического получения данных. Чтобы получить доступ к статистике по шагам (например, общему количеству шагов за день или за последние шесть часов), в сервисе "Здоровье и спорт" также можно использовать отслеживание шагов на устройстве под управлением Android 14 или более поздней версии.

В некоторых случаях может потребоваться отслеживание датчиков устройства с помощью SensorManager. SensorManager не запрашивает запрет блокировки от имени приложения, если только датчик не является датчиком пробуждения, который можно идентифицировать с помощью API isWakeUpSensor.

Рекомендация

Запись данных с датчиков с высокой частотой дискретизации может значительно разряжать батарею. Вот несколько рекомендаций, которые помогут снизить расход заряда и частоту запретов блокировки:

  • Если вы отслеживаете количество шагов или пройденное расстояние, используйте Recording API, чтобы записывать данные с минимальным расходом заряда батареи. Для устройств с Android 14 или более поздней версией ОС рекомендуем использовать Здоровье и спорт, чтобы получать доступ к истории данных и общему количеству шагов.
  • Для пассивного отслеживания датчиков в Wear OS используйте сервисы наблюдения за здоровьем, чтобы оптимизировать расход заряда батареи.
  • При регистрации датчика с помощью SensorManager задайте для maxReportLatencyUs значение больше 30 секунд, чтобы использовать логику пакетной обработки датчиков и уменьшить количество прерываний, получаемых приложением. Когда устройство выйдет из спящего режима по другой причине, например из-за действий пользователя, определения местоположения или запланированной задачи, система сразу же отправит кешированные данные датчиков.
  • Если вашему приложению требуются данные о местоположении и данные датчиков, синхронизируйте их получение и обработку. Объединяя показания датчиков с кратким запретом блокировки, который система удерживает для обновления местоположения, вы избегаете необходимости запрета блокировки для поддержания активности ЦП. Для загрузки и обработки этих объединенных данных используйте воркер или кратковременный запрет блокировки.

Firebase Cloud Messaging (FCM)

Запрет блокировки активируется при доставке широковещательного сообщения Firebase Cloud Messaging (FCM) в приложение и снимается после завершения метода onMessageReceived().

Названия запретов блокировки

Когда устройство получает сообщение FCM, на короткое время активируется запрет блокировки с названием GOOGLE_C2DM. На устройствах с Android 16 и более поздними версиями ОС запрет блокировки называется GCM_MESSAGE.

Рекомендация

Чтобы оптимизировать работу FCM, рекомендуем следовать приведенным ниже советам.

  • Оптимизируйте частоту доставки FCM.
  • Не используйте высокоприоритетные сообщения FCM, если сообщение не нужно доставить немедленно.
  • Метод onMessageReceived() должен выполняться как можно быстрее. Если требуется дополнительная обработка, запланируйте продолжение задачи с помощью рабочего процесса. Подробную информацию вы найдете в руководстве по Firebase.

JobScheduler

Задачи JobScheduler запрашивают запрет блокировки при выполнении в фоновом режиме. Запреты блокировки относятся к приложению, которое создало рабочие потоки.

Названия запретов блокировки

Названия запретов блокировки, полученных JobScheduler, зависят от версии Android и цели задачи.

Элементы в угловых скобках – это переменные. Например, "<package_name>" – это название пакета вашего приложения, а не текст <package name>. Однако *job* – это последовательность символов *job* со звездочками, которые не используются в качестве подстановочных знаков.

Android 15 и более ранних версий

Задания, инициированные пользователем, создают запреты блокировки с названиями, соответствующими следующему шаблону:

*job*u/@<name_space>@/<package_name>/<classname>

Другие задания используют этот шаблон:

*job*/@<name_space>@/<package_name>/<classname>
Android 16 QPR2 и более поздних версий

Задания, инициированные пользователем, создают запреты блокировки с названиями, соответствующими следующему шаблону:

*job*u/@<name_space>@/#<trace_tag>#/<package_name>/<classname>

Приоритетные задачи используют следующий шаблон:

*job*e/@<name_space>@/#<trace_tag>#/<package_name>/<classname>

Для обычных заданий используется следующий шаблон:

*job*r/@<name_space>@/#<trace_tag>#/<package_name>/<classname>
Пример

Предположим, что у вас есть приоритетная задача с пространством имен backup и тегом трассировки started. Название пакета – com.example.app, а класс, создавший задание, – com.backup.BackupFileService.

На устройствах с Android 15 или более ранней версией ОС запрет блокировки будет называться:

*job*/@backup@/com.example.app/com.backup.BackupFileService

На устройствах с Android 16 QPR2 или более поздней версии запрет блокировки будет называться:

*job*e/@backup@/#started#/com.example.app/com.backup.BackupFileService

Рекомендация

Местоположение

LocationManager и FusedLocationProviderClient используют запрет блокировки, чтобы получать и передавать данные о местоположении устройства. Запреты блокировки приписываются приложению, которое вызвало эти API.

Названия запретов блокировки

Сервисы геолокации используют следующие названия:

  • CollectionLib-SigCollector
  • NetworkLocationLocator
  • NetworkLocationScanner
  • NlpCollectorWakeLock
  • NlpWakeLock
  • *location*

Рекомендация

  • Ознакомьтесь с нашими рекомендациями по оптимизации использования местоположения. Попробуйте реализовать тайм-ауты, использовать пакетную обработку запросов местоположения или пассивные уведомления о местоположении.
  • Не используйте отдельный непрерывный запрет блокировки для кеширования данных о местоположении. Это избыточно и должно быть удалено. При запросе обновлений местоположения с помощью API FusedLocationProvider или LocationManager система автоматически активирует устройство во время обратного вызова события местоположения. Вместо этого сохраняйте события геолокации в памяти или хранилище и периодически обрабатывайте их с помощью WorkManager.

Дистанционный обмен сообщениями

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

  • Сопутствующие приложения для мониторинга видео или звука, которым нужно отслеживать события на внешнем устройстве, подключенном через локальную сеть.
  • Мессенджеры, которые поддерживают подключение к сокету сети с помощью версии для компьютера.

Большинство пробуждений в таких сценариях – это запреты блокировки ядра. Поскольку запреты блокировки на уровне ядра не связаны с приложением, здесь не указаны их названия.

Рекомендация

  • Если сетевые события можно обрабатывать на стороне сервера, используйте FCM для получения информации на клиенте. Если требуется дополнительная обработка данных FCM, вы можете запланировать срочную задачу.
  • Если события должны обрабатываться на стороне клиента с помощью сокет-соединения, запрет блокировки не требуется для прослушивания прерываний событий. Когда пакеты данных поступают на приемопередатчик Wi-Fi или мобильной сети, аппаратное обеспечение приемопередатчика запускает прерывание в виде запрета блокировки ядра. Затем вы можете запланировать работу или получить запрет блокировки для обработки данных.
  • Например, если вы используете ktor-network для прослушивания пакетов данных в сетевом сокете, запрет блокировки должен активироваться только после того, как пакеты будут доставлены клиенту.

WorkManager

Работники WorkManager получают запрет блокировки при выполнении задач в фоновом режиме. Запреты блокировки относятся к приложению, которое создало рабочие потоки.

Названия запретов блокировки

Названия запретов блокировки, полученных WorkManager, зависят от версии Android.

Android 15 и более ранних версий

Задачи WorkManager создают запреты блокировки с названиями, соответствующими следующему шаблону:

*job*/<package_name>/androidx.work.impl.background.systemjob.SystemJobService
Android 16 QPR2 и более поздних версий

Для срочных задач создаются запреты блокировки с названиями, соответствующими следующему шаблону:

*job*e/#<trace_tag>#/<package_name>/androidx.work.impl.background.systemjob.SystemJobService

Обычные задачи создаются по следующему шаблону:

*job*r/#<trace_tag>#/<package_name>/androidx.work.impl.background.systemjob.SystemJobService

По умолчанию <trace_tag> – это имя работника.

Пример

Предположим, что у вас есть сотрудник по имени BackupFileWorker, который занимается срочными заказами. Название пакета: com.example.app.

На устройствах с Android 15 или более ранней версией ОС запрет блокировки будет называться:

*job*/com.example.app/androidx.work.impl.background.systemjob.SystemJobService

На устройствах с Android 16 QPR2 или более поздней версией и WorkManager 2.10.0+ запрет блокировки будет называться:

*job*e/#BackupFileWorker#/com.example.app/androidx.work.impl.background.systemjob.SystemJobService

Рекомендация

  • Обновите WorkManager до последней стабильной версии, чтобы теги запрета блокировки были более подробными на устройствах с Android 16 QPR2 или более поздней версией.
  • Проверьте, как вы используете исполнителей WorkManager. В частности, убедитесь, что он соответствует нашим рекомендациям по оптимизации расхода заряда батареи для API планирования задач. Чтобы сделать теги запрета блокировки более подробными на устройствах с Android 16 QPR2 или более поздней версии, используйте метод setTraceTag для добавления дополнительной информации для отладки, например о том, какой класс запланировал работу.
  • Если вы обнаружили запреты блокировки, созданные WorkManager, с высоким уровнем использования, возможно, вы неправильно настроили Worker, и он не завершает работу в определенных сценариях. Рекомендуем проанализировать причины остановки рабочих процессов, особенно если часто возникает ошибка STOP_REASON_TIMEOUT.
  • Помимо регистрации причин остановки рабочих процессов, ознакомьтесь с нашей документацией по отладке рабочих процессов. Также рекомендуем собирать и анализировать трассировки системы, чтобы понимать, когда запреты блокировки устанавливаются и снимаются.

_UNKNOWN

Если инструменты отладки обнаружат в названии запрета блокировки информацию, позволяющую идентифицировать личность, то не будут показывать это название. Вместо этого они помечают запрет блокировки как _UNKNOWN. Например, это может произойти, если в названии запрета блокировки есть адрес электронной почты.

Рекомендация

Следуйте рекомендациям по выбору названий для запретов блокировки и не используйте в них информацию, позволяющую идентифицировать личность. Если вы обнаружите запрет блокировки с названием _UNKNOWN, который относится к вашему приложению, попробуйте определить, что это за запрет, и переименуйте его.