WakeLock är en Android-mekanism som förhindrar att enheten går in i viloläge genom att hålla processorn eller skärmen aktiv. Bakgrundsuppgifter som att ladda ner filer, spela upp ljud eller spela in data kräver WakeLock för garanterad utförande utan avbrott. Enligt specifikationen Android Developers, 2025, leder felaktig användning av WakeLock till snabb batteriurladdning och kan orsaka blockering av appen i Google Play.
Huvudpunkter
WakeLock är ett systemlås som förbjuder Android att försätta enheten i lågenergiläge. Normalt stänger Android efter några sekunders inaktivitet av användaren av skärmen och för processorn i djupsömn (deep sleep), där bakgrundstrådar pausas. WakeLock förhindrar denna övergång genom att hålla CPU:n aktiv.
WakeLock-mekanismen hanteras via systemtjänsten PowerManager, som nås via metoden getSystemService(Context.POWER_SERVICE). Utvecklaren skapar ett WakeLock-objekt med angivande av låstyp och måste garanterat frigöra det efter slutförd uppgift, annars kommer enhetens batteri att laddas ur snabbt. Systemet frigör inte WakeLock automatiskt — detta är appens ansvar.
Med varje större Android-version skärper Google kontrollen över WakeLock. Från och med Android 9 (API 28) kan en bakgrundsapp inte få WakeLock utan giltig anledning, och systemet övervakar appar som missbrukar lås och kan tvinga dem att frigöras. I Android 12+ infördes ytterligare begränsningar för åtkomst till PowerManager för bakgrundsappar.
WakeLock krävs i scenarier där uppgiften inte kan avbrytas av att enheten går i viloläge: nedladdning av stor fil via instabil anslutning, videoinspelning, utförande av långa beräkningar utan användarmedverkan. Utan sömnlås går processorn i djupsömn, alla trådar (threads) fryser och uppgiften förblir oavslutad.
Google rekommenderar dock starkt att minimera användningen av WakeLock. I de flesta fall kan samma uppgift lösas med Foreground Service med notis, WorkManager eller JobScheduler. Dessa mekanismer tar hänsyn till batteri- och nätverksstatus, vilket förlänger enhetens batteritid.
WakeLock fungerar via systemtjänsten PowerManager som hanterar enhetens strömstatus. När en app begär lås via powerManager.newWakeLock() ökar systemet CPU:ns aktivitetsnivå och förhindrar övergång till djupsömn. Efter anrop av wakeLock.release() återgår systemet till normalt energisparläge.
Det är viktigt att förstå att WakeLock inte förhindrar alla energisparlägen. Doze Mode (viloläge Android 6+) kan ignorera WakeLock i vissa faser — en app med ett hållet WakeLock får inte nätverksåtkomst i Doze-underhållsfönster. Detta innebär att även ett aktivt WakeLock inte garanterar utförande av nätverksoperationer under den andra fasen av Doze.
Varje WakeLock är kopplat till PowerManager.WakeLock på ramverkssidan. Systemet håller räkning på aktiva lås på processnivå: om en process håller flera WakeLock summeras de och frigöring sker först efter anrop av release() för varje lås. Android stöder även wake lock timeouts — automatisk frigöring efter angivet intervall. Att förlita sig på timeout rekommenderas dock inte: uppgiften kan slutföras tidigare och den extra hålltiden minskar batteritiden.
När enheten går i viloläge (strömknappen) frigör Android tvångsmässigt alla SCREEN_DIM_WAKE_LOCK och SCREEN_BRIGHT_WAKE_LOCK men behåller PARTIAL_WAKE_LOCK. Detta innebär att skärmlåset inte kan hindra enheten från att stänga av displayen — endast PARTIAL_WAKE_LOCK kan fortsätta fungera efter att strömknappen tryckts in.
I Android finns flera WakeLock-typer, som var och en hanterar specifika enhetskomponenter. Valet av typ avgör vilka hårdvarukomponenter som förblir aktiva efter låsning. Felaktigt typval leder till överdriven energiförbrukning på grund av aktivering av onödiga moduler.
| Typ | CPU | Skärm | Tangentbord | När ska användas |
|---|---|---|---|---|
| PARTIAL_WAKE_LOCK | På | Av | Av | Filnedladdning, beräkningar |
| SCREEN_DIM_WAKE_LOCK | På | Dämpad | Av | Videospelare, presentation |
| SCREEN_BRIGHT_WAKE_LOCK | På | Ljus | Av | Spel (föråldrat) |
| FULL_WAKE_LOCK | På | Ljus | Ljus | Föråldrat (deprecated) |
PARTIAL_WAKE_LOCK är den mest använda och rekommenderade typen. Den håller CPU:n aktiv men låter skärmen och tangentbordsbelysningen stängas av. Detta är det optimala valet för bakgrundsuppgifter: datanedladdning, bildbehandling, synkronisering. Skärmen släcks efter systemets timeout, vilket sparar batteri vid utförande av arbete som är osynligt för användaren.
SCREEN_DIM_WAKE_LOCK, SCREEN_BRIGHT_WAKE_LOCK och FULL_WAKE_LOCK är markerade som föråldrade från och med Android 7 (API 24). De håller skärmen påslagen, vilket leder till betydande batteriförbrukning. Google rekommenderar att man istället använder FLAG_KEEP_SCREEN_ON via Activity.getWindow().addFlags() — denna flagga fungerar endast med aktiv Activity och kräver inte WAKE_LOCK-tillstånd, och systemet hanterar automatiskt skärmens hålltid.
WakeLock är en av de största batteriförbrukarna på Android. Varje sekund som sömnlåset hålls förbrukar extra energi eftersom processorn inte kan gå över till energieffektivt C-state. Google Power Dashboard-forskning visar att appar med felaktigt frigjorda WakeLock kan öka enhetens energiförbrukning med 30–50% i standby-läge.
Systemet övervakar appar som missbrukar WakeLock via komponenten Battery Historian. Utvecklaren kan analysera energiförbrukningsprofilen och upptäcka låckage — situationer där WakeLock skapades men inte frigjordes. Google Play Console visar WakeLock-statistik för publicerade appar och lång hålltid kan leda till dåliga recensioner.
Doze Mode och App Standby begränsar ytterligare WakeLock-funktionen. I den första fasen av Doze (Light Doze) tillåter systemet WakeLock i korta underhållsfönster. I den andra fasen (Deep Doze) kombineras WakeLock med andra lås och körs i ett gemensamt fönster. Om en app håller WakeLock i mer än 10 minuter utan användarinteraktion kan systemet tvinga frigöring och placera appen på svarta listan för batterioptimering.
Korrekt användning av WakeLock är en balans mellan behovet att utföra en uppgift och hänsyn till enhetens batteri. Google rekommenderar att följa några principer: frigör alltid WakeLock i finally eller via acquire(timeout), använd minimalt nödvändig låstyp och undvik långvarigt hållande utan absolut nödvändighet.
WakeLock bör frigöras i samma kodblock där det skapades. För garanterad frigöring vid undantag används konstruktionen try-finally eller Kotlins use-block. På Android 10+ visar systemet en varning i logcat om WakeLock hålls i mer än 60 sekunder: "WakeLock held for more than 60 seconds" — detta är en signal om möjligt läckage.
Metoden acquire(long timeout) frigör automatiskt WakeLock efter angiven tid i millisekunder. Detta är ett skyddsnät om frigöringskoden inte körs på grund av undantag eller bugg. Det rekommenderas att alltid ange en timeout som är lika med maximal förväntad exekveringstid för uppgiften plus 10–20% marginal.
Innan anrop av release() bör man kontrollera om WakeLock för närvarande hålls. Upprepat anrop av release() utan föregående acquire() orsakar RuntimeException: WakeLock under-locked. Det rekommenderas att lagra en statusflagga (isHeld) och före frigöring kontrollera wakeLock.isHeld().
Låt oss titta på korrekt skapande och frigöring av WakeLock i Kotlin. Exemplet visar asynkron datanedladdning med hållande av PARTIAL_WAKE_LOCK, garanterad frigöring i try-finally-blocket och angivande av timeout för skydd mot läckage. Tjänsten använder CoroutineScope med IO-dispatch för att utföra bakgrundsuppgiften.
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() {
// Simulering av filnedladdning
delay(30000)
}
override fun onDestroy() {
super.onDestroy()
scope.cancel()
if (wakeLock.isHeld()) {
wakeLock.release()
}
}
override fun onBind(intent: Intent): IBinder? = null
}
För att använda WakeLock måste du lägga till tillstånd i AndroidManifest.xml. WAKE_LOCK-tillståndet är normalt (normal) — det kräver ingen runtime-förfrågan från användaren och beviljas automatiskt vid installation av appen. Google Play kan dock vägra publicering om appen inte har ett tydligt användningsscenario för WakeLock.
<uses-permission
android:name="android.permission.WAKE_LOCK" />
<uses-permission
android:name="android.permission.DEVICE_POWER" />
WakeLock är en lågnivåmekanism och Google rekommenderar att den där möjligt ersätts med modernare API:er. Det främsta alternativet är Foreground Service med notis, som automatiskt håller CPU-låset under tjänstens drift. Systemet hanterar själv WakeLock för Foreground Service, vilket befriar utvecklaren från behovet av explicit förvärv och frigöring.
WorkManager är det näst viktigaste verktyget för bakgrundsuppgifter. Det garanterar utförande av arbete även när enheten går i Doze och efter omstart. WorkManager stöder hållande av lås (hold lock) internt — utvecklaren behöver inte arbeta explicit med PowerManager. Uppgiften körs i Doze-underhållsfönstret med automatisk hantering av sömnlåset.
För regelbundna uppgifter som kräver exakt tid används AlarmManager med setAndAllowWhileIdle(), som kan väcka enheten från Doze. AlarmManager är dock endast lämplig för korta operationer — den är inte avsedd för långvarigt hållande av WakeLock. Om uppgiften tar längre tid än 10 sekunder måste AlarmManager kombineras med en BroadcastReceiver som startar Foreground Service.
Vanliga frågor
WakeLock är ett systemlås som förhindrar Android-enheten från att gå in i viloläge. Det håller processorn eller skärmen aktiv och tillåter bakgrundsuppgifter (nedladdning, beräkningar) att köras utan avbrott. Hanteras via systemtjänsten PowerManager.
Huvudtyper: PARTIAL_WAKE_LOCK (CPU aktiv, skärm av) — rekommenderas; SCREEN_DIM_WAKE_LOCK (CPU + dämpad skärm); SCREEN_BRIGHT_WAKE_LOCK (CPU + ljus skärm). SCREEN_DIM, SCREEN_BRIGHT och FULL_WAKE_LOCK är föråldrade och ersatta av FLAG_KEEP_SCREEN_ON.
Ja, i manifestet måste android.permission.WAKE_LOCK deklareras. Detta är ett normalt tillstånd (normal permission) som beviljas automatiskt vid installation — det behöver inte begäras vid körning. Utan detta tillstånd returnerar anrop av newWakeLock() null eller kastar SecurityException.
Om release() inte anropas kan enheten inte gå in i viloläge. Batteriet kommer att laddas ur betydligt snabbare (upp till 50% extra förbrukning). Systemet registrerar läckaget i logcat och Battery Historian visar onormalt lång WakeLock-hålltid, vilket leder till negativa användarrecensioner.
För långa uppgifter, använd Foreground Service med notis — systemet hanterar WakeLock själv. För fördröjda och garanterade uppgifter, använd WorkManager, som internt stöder WakeLock. För korta schemalagda uppgifter — AlarmManager.
Sammanfattning
Vi utvecklar en mobil applikation nyckelfärdigt
IT Sectr skapar iOS- och Android-applikationer för startups och företag sedan 2017. Vi ger dig råd och föreslår den bästa lösningen.
Läs också