4

I know that it is best practice to release a wake_lock as soon as it is no more needed, but what happens if the Activity or Service, for example, that has acquired it finishes or is stopped before you release the lock? Is it automatically released by the system? I think the system should release them automatically in that case, but I can not find anything on the API docs..

EDIT: added more info

Looking at the PowerManager.WakeLock documentation, I've seen that the wake_locks are reference counted by default (read setReferenceCounted here), i.e. if we retrieve a wake lock in an activity with PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "myWakeLock"); wl.acquire(); and then the reference variable wl that holds it goes out of scope, then the wake lock is released because its reference count goes to zero... is it right?

EDIT: wrong understanding above

I think I've misunderstood the reference count concept above... it should mean that if I acquire twice the lock and release it only once, then the reference count is 1 and the lock is not yet released. If it is not reference counted, then I can acquire x times and then with a single release it is released.

Gianni Costanzi
  • 6,054
  • 11
  • 48
  • 74

4 Answers4

2

There seems to be a lot of misinformation spread on the web about this. WakeLocks as exposed in the Android API have a pretty complex lifecycle and there is really no other way than be super diligent about managing it.

If an Activity or Service stops without you releasing a wakelock the state is undefined. If you inspect the code (https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/os/PowerManager.java, search for "class WakeLock") you will see that they are released when they are garbage collected.

This, "when they are garbage collected", however, is an extremely loose statement. In practice it seems that devices pre-Lollipop er really slow to GC the wakelocks (we can pretend it's not happening at all for practical purposes), but on post-Lollipop devices with the ART runtime it seems that stray WakeLocks are garbage collected within a few seconds.

On your questions about reference counting, you can see in the Android code that the lock is released disregarding what count it has.

If you do a blame on the Android code you can also see that it has not changed much over the years - so it all comes down to how the GC behaves. So you need to be diligent, store the lock in a field on your activity/service and release/acquire in sensible places in the app lifecycle. But if at all possible you should not be using a wakelock, but just the Force Screen On trick that Gatekeeper links to in one of the other answers.

kamstrup
  • 91
  • 7
1

Only if the process is destroyed then will the wakelocks be released. Just by finishing the service / Activity wake_lock will not be released.

nandeesh
  • 24,740
  • 6
  • 69
  • 79
  • This seems strange to me... I acquire a wake lock with `PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "myWakeLock"); wl.acquire();` and I think it will be released as soon as the `wl` reference goes out of scope.. shouldn't it behave like that? – Gianni Costanzi Aug 26 '12 at 15:46
  • no, I dont think it happens this way, because your acquire call needs to pass through powerManager and then to kernel. So I think even powerManager will have a reference to wakelock, so it wont be garbage collected. Only when you call release will it unregister – nandeesh Aug 26 '12 at 15:59
  • I think I've misunderstood the reference-count concept for the wake locks, as I've written in the second edit above. – Gianni Costanzi Aug 26 '12 at 16:02
0

I believe this answer will help you leaps and bounds Force Screen On

The PowerManager API states that you should release a wakelock as soon as possible, using the PowerManager API is known for draining more battery. Also in it API it states:

*If you hold a partial wakelock, the CPU will continue to run, irrespective of any timers and even after the user presses the power button. In all other wakelocks, the CPU will run, but the user can still put the device to sleep using the power button.

http://developer.android.com/reference/android/os/PowerManager.html

Community
  • 1
  • 1
Gatekeeper
  • 6,708
  • 6
  • 27
  • 37
  • I don't need to keep Screen on, just CPU running for the time I'm doing my stuff in an `IntentService`. – Gianni Costanzi Aug 26 '12 at 15:44
  • @GianniCostanzi : What does your `IntentService` do? Are you sure you need to use a `wakelock`? – Squonk Aug 26 '12 at 15:53
  • @Squonk no, I'm not sure.. in one of my apps the `IntentService` notifies the user with a notification by working in background, checking a condition and playing a sound/vibration and on some devices I've seen that the sound does not play if the screen goes off even if the service is set to be a foreground service. In another app, my `IntentService` works in background to build a widget's `RemoteViews`, downloading some text and images from the Network. Isn't it unnecessary in your opinion for both this apps? – Gianni Costanzi Aug 26 '12 at 15:55
  • @GianniCostanzi : It depends on how your `IntentServices` are started. I use one for daily file downloads and it's triggered by an alarm (using `AlarmManager`) set for `RTC_WAKEUP`. In this case, the alarm itself performs the 'wake' in order for the `IntentService` to do its stuff. Once the `IntentService` thread has finished, the `IntentService` self-terminates and the system is no longer awake. That's how I understand it anyway. – Squonk Aug 26 '12 at 15:59
  • @Gianni Costanzi the API does state that the CPU will continue to run with a partial wakelock even if the user presses the power button, I would assume the CPU will continue to run under the partial wakelock even if switching between activities, and the the wakelock won't be released until the calling app has been fully closed. – Gatekeeper Aug 26 '12 at 16:01
  • @Squonk My intent services are started by a system or custom broadcast event. – Gianni Costanzi Aug 26 '12 at 16:02
0

As detailed in this answer if the process is killed then yes the wakelock is released. But if the service or activity finishes normally without releasing the answer should be no.

Community
  • 1
  • 1
Mr_and_Mrs_D
  • 32,208
  • 39
  • 178
  • 361