Инструкции

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

8 минут чтения
Alice Yuan
Инженер по связям с разработчиками

Понимая, что чрезмерный расход заряда батареи является одной из главных проблем для пользователей Android, Google предпринимает значительные шаги, чтобы помочь разработчикам создавать более энергоэффективные приложения. 1 марта 2026 года Google Play Store начал внедрять технические улучшения качества блокировки пробуждения для снижения расхода батареи. Эти улучшения будут постепенно внедряться в затронутые приложения в течение следующих недель. Приложения, которые постоянно превышают пороговое значение «Чрезмерная частичная блокировка пробуждения» в Android Vitals, могут столкнуться с ощутимыми последствиями для своего присутствия в магазине, включая предупреждения в описании приложения и исключение из таких разделов, как рекомендации.

appDetails.png

Пользователи могут увидеть предупреждение в описании вашего приложения в магазине, если оно превысит пороговое значение для недопустимого поведения.

Эта инициатива повысила эффективность использования батареи до ключевого показателя, наряду с показателями стабильности, такими как сбои и ANR. «Порог нежелательного поведения» определяется как удержание частичной блокировки пробуждения, не подпадающей под исключения, в течение как минимум двух часов в среднем при выключенном экране более чем в 5% пользовательских сессий за последние 28 дней . Блокировка пробуждения исключается, если это системная блокировка пробуждения, которая предоставляет очевидные преимущества для пользователя, которые нельзя дополнительно оптимизировать, такие как воспроизведение аудио, доступ к местоположению или передача данных по инициативе пользователя. Полное определение чрезмерного количества блокировок пробуждения можно найти в нашей документации по показателям Android .

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

Использование службы переднего плана вместо частичной блокировки пробуждения

Мы часто сталкиваемся с тем, что разработчики испытывают трудности с пониманием разницы между двумя понятиями при выполнении задач в фоновом режиме: службами переднего плана и частичными блокировками пробуждения.

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

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

Обратитесь к блок-схеме в разделе «Выбор правильного API для поддержания активности устройства», чтобы убедиться, что вы хорошо понимаете, какой инструмент использовать, чтобы избежать получения блокировки пробуждения в сценариях, где это не требуется.

Библиотеки сторонних разработчиков приобретают блокировки пробуждения.

Нередко приложение обнаруживает, что оно помечено как имеющее чрезмерное количество блокировок пробуждения, удерживаемых сторонним SDK или системным API, действующим от его имени. Для выявления и устранения этих блокировок пробуждения мы рекомендуем следующие шаги:

  • Проверьте основные параметры Android: найдите точное имя проблемной блокировки пробуждения на панели мониторинга чрезмерных частичных блокировок пробуждения . Сравните это имя с руководством « Идентификация блокировок пробуждения, созданных другими API», чтобы определить, была ли она создана известным системным API или библиотекой Jetpack. Если да, вам может потребоваться оптимизировать использование API, и вы можете обратиться к рекомендуемым рекомендациям.
  • Создание трассировки системы: Если причину блокировки пробуждения не удается легко определить, воспроизведите проблему с блокировкой пробуждения локально, используя трассировку системы, и проанализируйте ее с помощью пользовательского интерфейса Perfetto. Подробнее о том, как это сделать, можно узнать в разделе «Отладка других типов чрезмерных блокировок пробуждения».   раздел этой записи в блоге .
  • Рассмотрите альтернативы: если проблема связана с неэффективной сторонней библиотекой, которую невозможно настроить с учетом времени автономной работы, рассмотрите возможность сообщить о проблеме владельцам SDK, найти альтернативный SDK или разработать функциональность собственными силами.

Типичные сценарии блокировки пробуждения

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

Загрузка или скачивание, инициированное пользователем.

Примеры вариантов использования:

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

Как уменьшить количество блокировок пробуждения:

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

Разовые или периодические фоновые синхронизации

Примеры вариантов использования:

  • Приложение периодически выполняет фоновую синхронизацию для получения данных для доступа в автономном режиме.
  • Приложения-шагомеры, которые периодически подсчитывают количество шагов.

Как уменьшить количество блокировок пробуждения:

  • Не используйте блокировку пробуждения вручную. Используйте WorkManager , настроенный для разовой или периодической работы. WorkManager заботится о состоянии системы, объединяя задачи в пакеты, и имеет минимальный периодический интервал (15 минут), которого обычно достаточно для фоновых обновлений.
  • Если вы обнаружили блокировки пробуждения, создаваемые WorkManager или JobScheduler, с высокой частотой их использования, это может быть связано с неправильной настройкой вашего рабочего процесса, из-за которой он не завершается в определенных сценариях. Рекомендуется проанализировать причины остановки рабочего процесса , особенно если вы наблюдаете частое появление ошибки STOP_REASON_TIMEOUT .
workManager.getWorkInfoByIdFlow(syncWorker.id)
  .collect { workInfo ->
      if (workInfo != null) {
        val stopReason = workInfo.stopReason
        logStopReason(syncWorker.id, stopReason)
      }
  }
  • Помимо регистрации причин остановки рабочих процессов, ознакомьтесь с нашей документацией по отладке рабочих процессов . Также рекомендуется собирать и анализировать системные трассировки , чтобы понять, когда захватываются и снимаются блокировки пробуждения.
  • Наконец, ознакомьтесь с нашим примером использования WHOOP , где они смогли обнаружить проблему в конфигурации своих рабочих узлов и значительно уменьшить влияние блокировки пробуждения.

Связь по Bluetooth

Примеры вариантов использования:

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

Как уменьшить количество блокировок пробуждения:

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

Отслеживание местоположения

Примеры вариантов использования:

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

Как уменьшить количество блокировок пробуждения:

  • Ознакомьтесь с нашими рекомендациями по оптимизации использования местоположения . Рассмотрите возможность внедрения тайм-аутов, использования пакетной обработки запросов на определение местоположения или пассивного обновления местоположения для обеспечения эффективного использования заряда батареи.
  • При запросе обновлений местоположения с использованием API FusedLocationProvider или LocationManager система автоматически запускает пробуждение устройства во время обратного вызова события определения местоположения. Эта кратковременная, управляемая системой блокировка пробуждения исключает необходимость в чрезмерных вычислениях частичной блокировки пробуждения.
  • Избегайте получения отдельной, непрерывной блокировки пробуждения для кэширования данных о местоположении, поскольку это избыточно. Вместо этого сохраняйте события определения местоположения в памяти или локальном хранилище и используйте WorkManager для их обработки через периодические интервалы.
override fun onCreate(savedInstanceState: Bundle?) {
    locationCallback = object : LocationCallback() {
        override fun onLocationResult(locationResult: LocationResult?) {
            locationResult ?: return
            // System wakes up CPU for short duration
            for (location in locationResult.locations){
                // Store data in memory to process at another time
            }
        }
    }
}

Мониторинг высокочастотных датчиков

Примеры вариантов использования:

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

Как уменьшить количество блокировок пробуждения:

  • При использовании SensorManager сократите интервалы его использования до периодических и только тогда, когда пользователь явно предоставил доступ через взаимодействие с пользовательским интерфейсом. Высокочастотный мониторинг датчиков может сильно разряжать батарею из-за большого количества пробуждений процессора и выполняемых операций.
  • Если вы отслеживаете количество шагов или пройденное расстояние, вместо использования SensorManager воспользуйтесь Recording API или рассмотрите возможность использования Health Connect для доступа к историческим и сводным данным о количестве шагов на устройстве, чтобы собирать данные экономичным с точки зрения энергопотребления способом.
  • При регистрации датчика в SensorManager укажите значение maxReportLatencyUs равное 30 секундам или более, чтобы использовать пакетную обработку данных с датчиков и минимизировать частоту прерываний ЦП. Когда устройство впоследствии будет активировано другим триггером, таким как взаимодействие с пользователем, определение местоположения или запланированное задание, система немедленно отправит кэшированные данные датчика.
val accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)

sensorManager.registerListener(this,
                 accelerometer,
                 samplingPeriodUs, // How often to sample data
                 maxReportLatencyUs // Key for sensor batching 
              )
  • Если вашему приложению требуются как данные о местоположении, так и данные с датчиков, синхронизируйте получение и обработку событий, связанных с ними. Используя данные с датчиков в качестве временной привязки к кратковременной блокировке системы для обновления местоположения, вы избегаете необходимости в дополнительной блокировке для поддержания активности процессора. Для обработки и загрузки этих объединенных данных используйте рабочий процесс или кратковременную блокировку.

Удалённый обмен сообщениями

Примеры вариантов использования:

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

Как уменьшить количество блокировок пробуждения:

  • Если сетевые события могут обрабатываться на стороне сервера, используйте FCM для получения информации на стороне клиента. При необходимости дополнительной обработки данных FCM можно запланировать выполнение задачи в ускоренном режиме .
  • Если обработка событий должна осуществляться на стороне клиента через сокетное соединение, блокировка пробуждения для прослушивания прерываний событий не требуется. Когда пакеты данных поступают на Wi-Fi или сотовую связь, радиооборудование инициирует аппаратное прерывание в виде блокировки пробуждения ядра. Затем вы можете запланировать выполнение рабочего процесса или получить блокировку пробуждения для обработки данных.
  • Например, если вы используете ktor-network для прослушивания пакетов данных на сетевом сокете, вам следует получать блокировку пробуждения только тогда, когда пакеты доставлены клиенту и нуждаются в обработке.
val readChannel = socket.openReadChannel()
while (!readChannel.isClosedForRead) {
    // CPU can safely sleep here while waiting for the next packet
    val packet = readChannel.readRemaining(1024) 
    if (!packet.isEmpty) {
         // Data Arrived: The system woke the CPU and we should keep it awake via manual wake lock (urgent) or scheduling a worker (non-urgent)
         performWorkWithWakeLock { 
              val data = packet.readBytes()
              // Additional logic to process data packets
         }
    }
}

Краткое содержание

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

    Автор:

    Продолжить чтение