Android - How to deal with (orphaned) WakeLocks?
How can I tell I'm affected?
This is probably the first question to those not familiar with this topic. With Gingerbread (Android 2.3) and above, you've got a service aboard helping you to figure out: battery statistics. Though manufacturers tend to place it at different points, it's mostly found in Settings → About the phone → Battery or similar, and shows a list of the apps having used most of your battery. On top of that is a small graph. Tap that, and it brings you to a screen similar to this one:
Screenshot of battery statistics on Android 2.3
I chose a screenshot from one of my devices which illustrates the issue. Looking at the lower two blue bars ("Aktiv" = Device was kept awake (active), "Bildschirm an" = "Screen on"), the right-most blue bar on "Aktiv" indicates a WakeLock: Device was kept busy despite the fact the screen was turned off. So by this we can be pretty sure we've got a WakeLock -- but we cannot tell who caused it.
If your device does not offer this screen (or the bars at the bottom: I just discovered e.g. the LG Optimus 4X running Android 4.0.3 has cut these bars off), you can find them e.g. using GSam Battery Monitor:
Similar information from GSam Battery Monitor -- here the mentioned "blue bars" are yellow/orange
What caused the WakeLock?
Unfortunately, this question cannot be answered using pre-installed apps (except for, maybe, some Custom ROMs). But there are tools available that can. The best known candidate for this is BetterBatteryStats, and shows us the cause in its partial wakelocks section:
Screenshots from BetterBatteryStats
In the first example2 (taken from the app's playstore page), the event causing most of the WakeLocks was a desired one: We don't want the playback stopped while listening to music. So the second example3 (taken from a real case on one of my devices) might prove better: the topmost 3 events are caused by the very same app, which needed the WakeLock to keep the IMAP push service active.
For an alternative to BetterBatteryStats, check out the Wakelock Detector app mentioned in UzumApps' answer -- which seems easier to handle especially for non-techies:
Wakelock Detector -- Click image to enlarge. (Source: Google Play)
What can be done?
If the case is as clear as in the second example in the previous section, the action is quite obvious -- at least in my case: I don't need to be informed immediately when a mail arrives; a delay of 30min is absolutely acceptable. So I went into the mail app, disabled IMAP Push (see also: Push Email), and instead switched to a 30min poll interval. WakeLocks did not entirely disappear, but dropped markably -- battery life improved noticably.
Then there's the case mentioned in the question itself: A bad behaving app not releasing its WakeLock. Confront the dev with your findings and ask for a fix. If he delivers: problem solved. If not: There's almost always an alternative app available.
What if it is the Android System itself?
Yeah, sometimes it looks like just that: 98% or more consumed by some Android service. Oh, if it's 98%, in most cases the candidate is named LocationManagerService. Bad guy spying at us? Not necessarily. In this special case, the listed "bad guy" is not even guilty -- at least not directly. Here it is another app requesting the current location too frequently. There's an excellent article on Setera.org about this: Pinpointing Android LocationManagerService battery drain. To give an abstract: It uses Android's dumpsys
feature (requires root!) to dump a system state, and lets you investigate the listeners established for the LocationManagerService. A closer look at their configuration shows which are constantly "hammering" it for location info (some do so permanently, i.e. without a break). As the app's ID is listed along, and at another place in the dump even together with the apps technical name, you can still identify it and take appropriate actions.
And what about UFOs?
Unfortunately, there are such: Apps which registered a WakeLock -- and then exited without releasing it. What's left are *Unused F***ing Obsoletes* -- WakeLocks held for no use. So no way to simply bring the app to foreground and re-configure, or making it release its WakeLocks.
Here the only solution known to me is a reboot -- and I would like to have a better solution. Of course, if you know the guilty app, the steps concerning it are the same as above: inform the dev, get a fix -- or replace the app. But about getting rid of the current WakeLock? Maybe somebody else can provide a better alternative to the reboot?
Are there some recommended further readings?
Sure. One for now, I may add more later:
- [GUIDE] Wakelocks Definition and how to prevent them (XDA Developers, March 2013)
In short, this is a very good question but am afraid, it warrants more than just making the end-user aware!
Redesign the kernel to eliminate wake-locks and use a more thorough efficient way of managing the principle better thereby prolonging battery life.
Unfortunately, it has been accepted as a de-facto solution to enable "power management" despite it is not exactly efficient either! There was an extensive discussion about wakelocks (with Gregh Kroah Hartman - the Linux guru for drivers development - am googling for the exact linky), other sites such as LWN.net and another article explained on the same site here. This was the article Gregh Kroah Hartman referred to this blog, in which he appears to agree with the alternative solution proposed by Rafael J. Wysocki have documented a lot about the potential alternative. Am not sure if that is actually in place in the more modern kernel v3.x.x.
Badly designed apps can and often request wakelocks such as keeping the screen on, but in fact, in this scenario for keeping the screen on, there is in fact a more efficient way to do this:
getWindow().addFlags(LayoutParams.FLAG_KEEP_SCREEN_ON);
Whilst, striving to keep this clear of jargon etc for the end user, really the core of the issue boils down to the kernel code in how the wakelocks are managed.
Here is a brief summary on XDA on what is wakelocks for the uninitiated. By using BetterBatteryStats, one could see exactly which process is draining the battery, the wiki is hosted on github, and is available on the market here.
Check out Wakelock Detector: XDA-Developers / Google Play:
Wakelock detector groups the wakelocks of app into one expandable view for better look. And it shows which apps are running. And there are kill uninstall info buttons in expanded view of app.
Click image to enlarge. (Source: Google Play)
Disclosure: I am one of responsible developer for this app. Four more friends are with me working on this project as a hobby.