Новости о продуктах

Как оптимизировать расход заряда батареи с помощью показателя запрета блокировки в Android Vitals

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

Время работы от батареи – важный аспект удобства использования, и запреты блокировки играют в этом большую роль. Не слишком ли часто вы их используете? В этой записи блога мы расскажем, что такое запрет блокировки, как его использовать и как с помощью показателя в Play Console лучше понять, как работает ваше приложение.

Слишком долгая работа частичных запретов блокировки в Android Vitals

Теперь в Play Console можно отслеживать расход батареи. Ключевым показателем эффективности является слишком долгая работа частичных запретов блокировки.

Эта функция повышает важность эффективности батареи наряду с существующими основными показателями стабильности: чрезмерным количеством сбоев в активном режиме и ошибками ANR. Мы определили порог соответствия для слишком длительных запретов блокировки. С 1 марта 2026 года мы можем исключать из рекомендаций и других заметных разделов Google Play продукты, которые не соответствуют этому порогу качества. В некоторых случаях на странице приложения в Google Play пользователям может показываться предупреждение о том, что ваше приложение может вызывать чрезмерный расход заряда батареи.

warning.png

Предупреждение о слишком частом запрете блокировки в обзоре Android Vitals.

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

  • Запрет блокировки действует не менее двух часов в течение 24-часового периода.
  • Она затрагивает более 5% сеансов в приложении (среднее значение за 28 дней).

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

Что такое запрет блокировки

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

При частичном запрете блокировки ЦП продолжает работать, даже если экран выключен, и не переходит в режим ожидания с низким энергопотреблением. При полном запрете блокировки экран и ЦП продолжают работать.

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

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

Запрет блокировки необходим для выполнения таких задач, как скачивание большого файла, инициированное пользователем. Однако чрезмерное или неправильное использование этой функции может привести к значительному расходу заряда батареи. Мы сталкивались со случаями, когда приложения удерживали запрет блокировки часами или не снимали его должным образом. Это приводило к жалобам пользователей на значительный расход заряда батареи, даже когда они не взаимодействовали с приложением.

Рекомендации по использованию запрета блокировки

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

Рассмотрим четыре критических вопроса.


1. Рассматривали ли вы альтернативные варианты запрета блокировки?

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

wakelock.png

Блок-схема, которая поможет решить, когда нужно вручную запретить блокировку

  1. Должен ли экран оставаться включенным?
  2. Запущена ли в приложении активная служба?
    • Нет. Вам не нужно вручную запрашивать запрет блокировки.
  3. Будет ли приостановка работы устройства мешать пользователю?
    • Нет. Например, чтобы обновить уведомление после выхода устройства из спящего режима, запрет блокировки не требуется.
    • Да. Если важно, чтобы устройство не переходило в спящий режим, например для поддержания связи с внешним устройством, продолжите.
  4. Есть ли API, который не дает устройству перейти в спящий режим?
    • Чтобы определить, в каких случаях запреты блокировки создаются другими API, например LocationManager, воспользуйтесь документацией Identify wake locks created by other APIs.
    • Если API нет, перейдите к последнему вопросу.
  5. Если вы ответили на все эти вопросы и определили, что альтернативы нет, вам следует вручную получить запрет блокировки.

2. Правильно ли вы называете запрет блокировки?

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

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

3. Всегда ли снимается запрет блокировки?

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

Например, если во время processingWork() возникает необработанное исключение, вызов release() может не произойти. Вместо этого используйте блок try-finally, чтобы гарантировать снятие запрета блокировки, даже если возникнет исключение.

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

fun processingWork() {
    wakeLock.apply {
        try {
            acquire(60 * 10 * 1000) // timeout after 10 minutes
            doTheWork()
        } finally {
            release()
        }
    }
}

4. Можно ли уменьшить частоту пробуждения?

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

  • WorkManager. Увеличьте периодический интервал в PeriodicWorkRequest.
  • SensorManager. Используйте пакетную обработку, указав maxReportLatencyMs при регистрации прослушивателя.
  • Fused Location Provider:
    • Чтобы реже запрашивать данные о местоположении, используйте метод getLastLocation, который возвращает последнее сохраненное в кеше местоположение.
    • Используйте setPriority(PRIORITY_PASSIVE), чтобы снизить расход заряда батареи.
    • Вы также можете использовать механизм пакетной обработки местоположений, установив минимальный интервал обновления с помощью setMinUpdateIntervalMillis.

Подробную информацию можно найти в документации по рекомендациям для запрета блокировки.

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

Даже при самых лучших намерениях может возникнуть чрезмерное использование запрета блокировки. Если в Play Console появилось предупреждение о вашем приложении, выполните следующие действия:

Первоначальная идентификация в Play Console

На панели Android Vitals, посвященной слишком частому частичному запрету блокировки, можно посмотреть названия запретов, которые не относятся к исключениям и связаны с вашим приложением, а также затронутые сеансы и их продолжительность. Напоминаем, что определить, кем удерживается запрет блокировки (приложением или другим API), можно с помощью документации.

breakdowns2.png

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

Отладка чрезмерного запрета блокировки, удерживаемого рабочими процессами или заданиями

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

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

Полный список вариантов названий запретов блокировки, удерживаемых рабочими процессами, доступен в документации. Для отладки запретов блокировки можно использовать инспектор фоновых задач (локально) или метод getStopReason (в полевых условиях).

Инспектор фоновых задач Android Studio

taskinspector.png


Скриншот инспектора фоновых задач, на котором показан исполнитель WeatherSyncWorker, часто повторяющий попытки и завершающийся сбоем.

Для локальной отладки проблем с WorkManager используйте этот инструмент на эмуляторе или подключенном устройстве (API уровня 26 или выше). Он показывает список рабочих процессов и их статусы (завершен, выполняется, в очереди), позволяя просматривать подробности и понимать цепочки рабочих процессов. 

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

Подробную информацию можно найти в документации по инспектору фоновых задач.

WorkManager getStopReason

Для отладки рабочих процессов с чрезмерным количеством запретов блокировки используйте WorkInfo.getStopReason() в WorkManager 2.9.0 или более поздней версии, а для JobScheduler – JobParameters.getStopReason() в SDK 31 или более поздней версии. 

Этот API помогает регистрировать причину остановки воркера (например, STOP_REASON_TIMEOUT, STOP_REASON_QUOTA), выявляя такие проблемы, как частые тайм-ауты из-за исчерпания времени выполнения.

backgroundScope.launch {
    WorkManager.getInstance(context)
        .getWorkInfoByIdFlow(workRequest.id)
        .collect { workInfo ->
            logStopReason(workRequest.id, workInfo?.stopReason)
        }
}

Подробнее об оптимизации расхода заряда батареи при использовании API для планирования задач…

Как отлаживать другие типы запретов блокировки

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

Сбор данных трассировки системы

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

Записать трассировку системы можно несколькими способами: 

powermgmt.png

Включите категорию Atrace power:PowerManagement в интерфейсе Perfetto на вкладке Android apps & svcs (Приложения и сервисы Android). 

Независимо от выбранного метода, важно убедиться, что вы собираете категорию Atrace "power:PowerManagement", чтобы включить просмотр дорожек состояния устройства. 

Проверка интерфейса Perfetto и анализ SQL

Файлы трассировки системы можно открывать и изучать в Perfetto UI. Открыв трассировку, вы увидите визуализацию различных процессов на временной шкале. В этом руководстве мы сосредоточимся на версиях в разделе "Состояние устройства".

perfetto.png


Закрепите дорожки в разделе Device State (Состояние устройства), например Top app (Основное приложение), Screen state (Состояние экрана), Long Wake locks (Длительные запреты блокировки) и Jobs (Задания), чтобы визуально определить длительные запреты блокировки.

В каждом блоке указано название мероприятия, а также время его начала и окончания. В Perfetto это называется срезом.

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

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

SELECT slice.name as name, track.name as track_name,SUM(dur / 100000) as total_dur_ms
FROM slice
JOIN track ON slice.track_id = track.id
WHERE track.name = 'WakeLocks'GROUP BY slice.name, track.name
ORDER BY total_dur_ms DESC

Как использовать ProfilingManager для сбора трассировок в полевых условиях

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

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

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

Заключение

Показатель "Слишком долгая работа частичных запретов блокировки" в Android Vitals – это лишь малая часть того, что мы делаем, чтобы помочь разработчикам снизить расход батареи и повысить качество приложений. 

Правильно настроив запрет блокировки, вы сможете значительно оптимизировать расход заряда батареи. Чтобы приложение было успешным в Google Play, используйте альтернативные API, следуйте рекомендациям по запрету блокировки и применяйте эффективные инструменты отладки, такие как инспектор фоновых задач, трассировка системы и ProfilingManager.

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