WakeLock — это механизм Android, который предотвращает перевод устройства в режим сна, удерживая процессор или экран в активном состоянии. Фоновые задачи, такие как загрузка файлов, воспроизведение аудио или запись данных, требуют WakeLock для гарантированного выполнения без прерываний. Согласно спецификации Android Developers, 2025, некорректное использование WakeLock приводит к быстрому разряду батареи и может стать причиной блокировки приложения в Google Play.
Главное
WakeLock — это системная блокировка, которая запрещает Android переводить устройство в режим пониженного энергопотребления. Обычно Android через несколько секунд бездействия пользователя отключает экран и переводит процессор в состояние глубокого сна (deep sleep), при котором фоновые потоки приостанавливаются. WakeLock предотвращает этот переход, удерживая CPU в активном режиме.
Механизм WakeLock управляется через системный сервис PowerManager, доступ к которому осуществляется через метод getSystemService(Context.POWER_SERVICE). Разработчик создаёт объект WakeLock, указывая тип блокировки, и должен гарантированно освободить его после завершения задачи, иначе аккумулятор устройства будет быстро разряжаться. Система не освобождает WakeLock автоматически — это ответственность приложения.
С каждым мажорным релизом Android Google ужесточает контроль над WakeLock. Начиная с Android 9 (API 28), приложение в фоне не может получить WakeLock без веской причины, а система отслеживает приложения, злоупотребляющие блокировками, и может принудительно их освобождать. В Android 12+ были введены дополнительные ограничения на доступ к PowerManager для background-приложений.
WakeLock требуется в сценариях, где задача не может быть прервана переходом устройства в сон: загрузка большого файла по нестабильному соединению, запись видео, выполнение длительных вычислений без участия пользователя. Без блокировки сна процессор переходит в глубокий сон, все потоки (threads) замораживаются, и задача остаётся незавершённой.
Однако Google настоятельно рекомендует минимизировать использование WakeLock. В большинстве случаев ту же задачу можно решить с помощью Foreground Service с уведомлением, WorkManager или JobScheduler. Эти механизмы учитывают состояние батареи и сети, что продлевает время автономной работы устройства.
WakeLock работает через системный сервис PowerManager, который управляет состоянием питания устройства. Когда приложение запрашивает блокировку через powerManager.newWakeLock(), система повышает уровень активности CPU, предотвращая переход в глубокий сон. После вызова wakeLock.release() система возвращается к штатному режиму энергосбережения.
Важно понимать, что WakeLock не предотвращает все режимы энергосбережения. Doze Mode (режим сна Android 6+) может игнорировать WakeLock в определённых фазах — приложение с удержанным WakeLock не получит доступ к сети в окнах обслуживания Doze. Это означает, что даже активный WakeLock не гарантирует выполнение сетевых операций во время второй фазы Doze.
Каждый WakeLock связан с PowerManager.WakeLock на стороне framework. Система ведёт подсчёт активных блокировок на уровне процесса: если один процесс удерживает несколько WakeLock, они суммируются, и освобождение происходит только после вызова release() для каждой блокировки. Android также поддерживает wake lock timeouts — автоматическое освобождение через заданный интервал. Однако полагаться на timeout не рекомендуется: задача может завершиться раньше, и лишнее время удержания сократит ресурс батареи.
При переходе устройства в спящий режим (кнопка питания) Android принудительно освобождает все SCREEN_DIM_WAKE_LOCK и SCREEN_BRIGHT_WAKE_LOCK, но сохраняет PARTIAL_WAKE_LOCK. Это означает, что блокировка экрана не может удержать устройство от выключения дисплея — только PARTIAL_WAKE_LOCK способен продолжать работу после нажатия кнопки питания.
В Android существует несколько типов WakeLock, каждый из которых управляет конкретными компонентами устройства. Выбор типа определяет, какие именно аппаратные компоненты остаются активными после блокировки. Неправильный выбор типа приводит к избыточному энергопотреблению из-за включения ненужных модулей.
| Тип | CPU | Экран | Клавиатура | Когда использовать |
|---|---|---|---|---|
| PARTIAL_WAKE_LOCK | Вкл | Выкл | Выкл | Загрузка файлов, вычисления |
| SCREEN_DIM_WAKE_LOCK | Вкл | Тусклый | Выкл | Видеоплеер, презентация |
| SCREEN_BRIGHT_WAKE_LOCK | Вкл | Яркий | Выкл | Игры (устаревший) |
| FULL_WAKE_LOCK | Вкл | Яркий | Яркая | Устаревший (deprecated) |
PARTIAL_WAKE_LOCK — самый часто используемый и рекомендуемый тип. Он удерживает CPU в активном режиме, но позволяет экрану и подсветке клавиатуры отключаться. Это оптимальный выбор для фоновых задач: загрузка данных, обработка изображений, синхронизация. Экран гаснет через системный тайм-аут, что экономит батарею при выполнении невидимой пользователю работы.
SCREEN_DIM_WAKE_LOCK, SCREEN_BRIGHT_WAKE_LOCK и FULL_WAKE_LOCK помечены как deprecated начиная с Android 7 (API 24). Они удерживают экран включённым, что приводит к значительному расходу батареи. Google рекомендует вместо них использовать FLAG_KEEP_SCREEN_ON через Activity.getWindow().addFlags() — этот флаг работает только при активной Activity и не требует разрешения WAKE_LOCK, а система автоматически управляет временем удержания экрана.
WakeLock — один из главных «пожирателей» батареи на Android. Каждая секунда удержания блокировки сна потребляет дополнительную энергию, поскольку процессор не может перейти в энергоэффективное состояние C-state. Исследование Google Power Dashboard показывает, что приложения с некорректно освобождёнными WakeLock могут увеличить энергопотребление устройства на 30–50% в режиме ожидания.
Система отслеживает приложения, злоупотребляющие WakeLock, через компонент Battery Historian. Разработчик может проанализировать профиль энергопотребления и выявить «утечки» блокировок — ситуации, когда WakeLock был создан, но не освобождён. Google Play Console показывает статистику WakeLock для опубликованных приложений, и высокое время удержания может стать причиной плохих отзывов.
Doze Mode и App Standby дополнительно ограничивают работу WakeLock. В первой фазе Doze (Light Doze) система разрешает WakeLock в коротких окнах обслуживания. Во второй фазе (Deep Doze) WakeLock объединяется с другими блокировками и выполняется в общем окне. Если приложение удерживает WakeLock более 10 минут без пользовательского взаимодействия, система может принудительно освободить его и занести приложение в чёрный список оптимизации батареи.
Корректное использование WakeLock — это баланс между необходимостью выполнить задачу и заботой о батарее устройства. Google рекомендует придерживаться нескольких принципов: всегда освобождать WakeLock в finally или через acquire(timeout), использовать минимально необходимый тип блокировки и избегать длительного удержания без крайней необходимости.
WakeLock должен освобождаться в том же блоке кода, где был создан. Для гарантии освобождения при исключениях используется конструкция try-finally или use-блок Kotlin. На Android 10+ система выводит предупреждение в logcat, если WakeLock удерживается дольше 60 секунд: "WakeLock held for more than 60 seconds" — это сигнал о возможной утечке.
Метод acquire(long timeout) автоматически освобождает WakeLock через заданное время в миллисекундах. Это страховка на случай, если код освобождения не выполнится из-за исключения или бага. Рекомендуется всегда указывать timeout, равный максимальному ожидаемому времени выполнения задачи плюс 10–20% запаса.
Перед вызовом release() следует проверять, удерживается ли WakeLock в данный момент. Повторный вызов release() без предварительного acquire() вызывает RuntimeException: WakeLock under-locked. Рекомендуется хранить флаг состояния (isHeld) и перед освобождением проверять wakeLock.isHeld().
Рассмотрим корректное создание и освобождение WakeLock на Kotlin. Пример демонстрирует асинхронную загрузку данных с удержанием PARTIAL_WAKE_LOCK, гарантированным освобождением в блоке try-finally и указанием timeout для страховки от утечек. Сервис использует CoroutineScope с диспетчером IO для выполнения фоновой задачи.
class DownloadService : Service() {
private lateinit var wakeLock: PowerManager.WakeLock
private val scope = CoroutineScope(Dispatchers.IO + SupervisorJob())
override fun onCreate() {
super.onCreate()
val powerManager = getSystemService(Context.POWER_SERVICE) as PowerManager
wakeLock = powerManager.newWakeLock(
PowerManager.PARTIAL_WAKE_LOCK,
"download:wakelock"
)
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
wakeLock.acquire(60000)
scope.launch {
try {
downloadFile()
} finally {
if (wakeLock.isHeld()) {
wakeLock.release()
}
}
}
return START_NOT_STICKY
}
private suspend fun downloadFile() {
// Имитация загрузки файла
delay(30000)
}
override fun onDestroy() {
super.onDestroy()
scope.cancel()
if (wakeLock.isHeld()) {
wakeLock.release()
}
}
override fun onBind(intent: Intent): IBinder? = null
}
Для использования WakeLock необходимо добавить разрешение в AndroidManifest.xml. Разрешение WAKE_LOCK является нормальным (normal) — оно не требует runtime-запроса у пользователя и предоставляется автоматически при установке приложения. Тем не менее, Google Play может отклонить публикацию, если в приложении нет очевидного сценария использования WakeLock.
<uses-permission
android:name="android.permission.WAKE_LOCK" />
<uses-permission
android:name="android.permission.DEVICE_POWER" />
WakeLock — низкоуровневый механизм, и Google рекомендует по возможности заменять его более современными API. Основная альтернатива — Foreground Service с уведомлением, который автоматически удерживает CPU-блокировку на время работы сервиса. Система сама управляет WakeLock для Foreground Service, освобождая разработчика от необходимости явного захвата и освобождения.
WorkManager — второй по значимости инструмент для фоновых задач. Он гарантирует выполнение работы даже при переходе устройства в Doze и после перезагрузки. WorkManager поддерживает держатель WakeLock (hold lock) внутри себя — разработчику не нужно явно работать с PowerManager. Задача выполняется в окне обслуживания Doze с автоматическим управлением блокировкой сна.
Для регулярных задач, требующих точного времени, используется AlarmManager с setAndAllowWhileIdle(), который может пробудить устройство из Doze. Однако AlarmManager подходит только для коротких операций — он не предназначен для длительного удержания WakeLock. Если задача выполняется дольше 10 секунд, следует комбинировать AlarmManager с BroadcastReceiver, который запускает Foreground Service.
Часто задаваемые вопросы
WakeLock — это системная блокировка, которая предотвращает переход Android-устройства в спящий режим. Она удерживает процессор или экран в активном состоянии, позволяя фоновым задачам (загрузка, вычисления) выполняться без прерывания. Управляется через системный сервис PowerManager.
Основные типы: PARTIAL_WAKE_LOCK (CPU активен, экран выключен) — рекомендуется; SCREEN_DIM_WAKE_LOCK (CPU + тусклый экран); SCREEN_BRIGHT_WAKE_LOCK (CPU + яркий экран). SCREEN_DIM, SCREEN_BRIGHT и FULL_WAKE_LOCK помечены как deprecated и заменены на FLAG_KEEP_SCREEN_ON.
Да, в манифесте требуется объявить android.permission.WAKE_LOCK. Это нормальное разрешение (normal permission), которое предоставляется автоматически при установке — не нужно запрашивать его в runtime. Без этого разрешения вызов newWakeLock() вернёт null или выбросит SecurityException.
Если не вызвать release(), устройство не сможет перейти в спящий режим. Аккумулятор будет разряжаться значительно быстрее (до 50% дополнительного расхода). Система зафиксирует утечку в logcat, а Battery Historian покажет аномальное время удержания WakeLock, что приведёт к плохим отзывам пользователей.
Для длительных задач используйте Foreground Service с уведомлением — система сама управляет WakeLock. Для отложенных и гарантированных задач используйте WorkManager, который поддерживает WakeLock внутри себя. Для коротких задач по расписанию — AlarmManager.
Итоги
Мы разработаем мобильное приложение под ключ
IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.
Читайте также