Оптимизация потребления батареи мобильным приложением
«Ваше приложение сажает батарею» — один из самых болезненных отзывов в сторе. iOS с iOS 16 показывает пользователям рейтинг потребления батареи по приложениям. Android с версии 12 активно сигнализирует о фоновых процессах через Battery Usage alerts. Приложение может работать корректно технически, но при этом быть в списке «прожорливых» — и пользователи его удалят.
Главные потребители: что показывает Battery Historian
Battery Historian — инструмент Google для анализа bugreport с Android устройства. Показывает временную шкалу: wakelock-ы, network activity, GPS фиксы, CPU wakeup. Типичная картина приложения с проблемным потреблением: wakelock каждые 15 минут на 2-3 секунды, периодические network запросы, GPS в фоне с высокой точностью.
Wakelock-и. PowerManager.WakeLock.acquire() без таймаута или без гарантированного release() — устройство не уходит в deep sleep. Одна незакрытая PARTIAL_WAKE_LOCK держит процессор активным всю ночь. Используем WakefulBroadcastReceiver или WorkManager, которые управляют wakelock автоматически.
WorkManager и неправильные интервалы. Периодическая задача с интервалом 15 минут (минимально допустимый) на устройстве с агрессивной Battery Optimization может работать реже. Но если в задаче есть сетевой запрос + запись в базу + GPS — 15 минут это слишком часто. JobScheduler batching: группируем задачи, используем setRequiredNetworkType(NetworkType.CONNECTED) чтобы не будить радио без сети.
GPS: главный убийца батареи
LocationManager с LocationRequest.PRIORITY_HIGH_ACCURACY (Fused Location Provider) включает GPS-приёмник и держит его активным. 1-2% батареи в час при непрерывном GPS — это реальные цифры на современных устройствах.
Правильная стратегия по типам приложений:
- Навигация в фоне:
PRIORITY_HIGH_ACCURACYтолько при активной навигации, переключение наPRIORITY_BALANCED_POWER_ACCURACYпри фоновом трекинге маршрута - Геофенсинг:
GeofencingClientвместо постоянного GPS — срабатывает только при входе/выходе из зоны, потребление минимальное - «Найти рядом»: разовый
getCurrentLocation()вместо постоянных обновлений
На iOS: CLLocationManager с desiredAccuracy = kCLLocationAccuracyBest в фоне — серьёзная проблема. significantLocationChangeMonitoring потребляет на порядок меньше и достаточен для большинства сценариев фоновой геолокации. allowsBackgroundLocationUpdates = true требует явного обоснования — без него iOS агрессивно ограничивает обновления.
Сетевые запросы и радио
Радиомодуль (Wi-Fi, LTE) при активации тратит дополнительную энергию на подъём соединения, даже если передаётся 1 байт. Закономерность: лучше один крупный запрос раз в 5 минут, чем 20 маленьких запросов каждые 15 секунд. Batching запросов через WorkManager с setRequiredNetworkType гарантирует, что запросы не разбудят радио без сети.
HTTP Keep-Alive и HTTP/2 multiplexing сокращают количество TCP handshake — это не только латентность, но и батарея.
Push-уведомления через FCM/APNs — это правильный способ сигнализировать о новых данных вместо long polling или short polling. Server-Sent Events и WebSocket приемлемы когда нужна реалтайм-коммуникация, но их нужно закрывать при уходе в фон.
iOS: Background App Refresh и BGTaskScheduler
BGAppRefreshTask и BGProcessingTask — современный API для фоновых задач на iOS. Система сама решает, когда их запустить, опираясь на паттерны использования устройства (ночью, на зарядке). Попытки обойти это через background audio trick или VoIP push для не-VoIP приложений — нарушение App Store Guidelines.
URLSession.shared.configuration.waitsForConnectivity = true — сетевые запросы не поднимают радио сразу, ждут готового соединения.
Практический кейс
Приложение для трекинга фитнес-активностей. Пользователи жаловались на 8-10% батареи в час в фоне. Battery Historian показал: CoreLocationManager с PRIORITY_HIGH_ACCURACY работал непрерывно, плюс PeriodicWorkRequest каждые 15 минут делал 4 сетевых запроса. Переключение на PRIORITY_BALANCED_POWER_ACCURACY для фонового трекинга + слияние сетевых запросов в один + увеличение интервала до 30 минут дало 1.5-2% в час — в 4-5 раз меньше, при сохранении функциональности.
Инструменты диагностики
Android: Battery Historian, Android Studio Energy Profiler, adb shell dumpsys batterystats
iOS: Xcode Instruments → Energy Log, MetricKit MXCPUMetric, Xcode Organizer → Battery Usage
Cross-platform: Firebase Performance Monitoring не трекает батарею, но трекает количество сетевых запросов и их размер — косвенный индикатор
Срок оптимизации — одна-две недели: диагностика, приоритизация, исправления.







