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 для фонових додатків.
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 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.