Инструкции

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

8 минут чтения
Посмотреть профиль Алисы Юань
Alice Yuan инженер по связям с разработчиками, Android

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

appDetails.png

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

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

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

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

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

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

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

Refer to the flow chart in Choose the right API to keep the device awake to ensure you have a strong understanding of what tool to use to avoid acquiring a wake lock in scenarios where it's not necessary.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  • Do not acquire a manual wake lock. Use WorkManager configured for one-time or periodic work. WorkManager respects system health by batching tasks and has a minimum periodic interval (15 minutes), which is generally sufficient for background updates.
  • If you identify wake locks created by WorkManager or JobScheduler with high wake lock usage, it may be because you've misconfigured your worker to not complete in certain scenarios. Consider analyzing the worker stop reasons , particularly if you're seeing high occurrences of 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 для доступа к историческим и сводным данным о количестве шагов на устройстве, чтобы собирать данные экономичным с точки зрения энергопотребления способом.
  • If you're registering a sensor with SensorManager , specify a maxReportLatencyUs of 30 seconds or more to leverage sensor batching to minimize the frequency of CPU interrupts. When the device is subsequently woken by another trigger such as a user interaction, location retrieval, or a scheduled job, the system will immediately dispatch the cached sensor data.
val accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)

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

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

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

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

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

  • If the network events can be processed on the server side, use FCM to receive information on the client. You may choose to schedule an expedited worker if additional processing of FCM data is required.
  • Если обработка событий должна осуществляться на стороне клиента через сокетное соединение, блокировка пробуждения для прослушивания прерываний событий не требуется. Когда пакеты данных поступают на 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
         }
    }
}

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

By adopting these recommended solutions for common use cases like background syncs, location tracking, sensor monitoring and network communication, developers can work towards reducing unnecessary wake lock usage. To continue learning, read our other technical blog post or watch our technical video on how to discover and debug wake locks: Optimize your app battery using Android vitals wake lock metric . Also, consult our updated wakelock documentation . To help us continue improving our technical resources, please share any additional feedback on our guidance in our documentation feedback survey .

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