In WakefileIntentService.java from the CWAC Wakeful library the code contains:
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
PowerManager.WakeLock lock = getLock(this.getApplicationContext());
if (!lock.isHeld() || (flags & START_FLAG_REDELIVERY) != 0) {
lock.acquire();
}
super.onStartCommand(intent, flags, startId);
return(START_REDELIVER_INTENT);
}
Why do the code check for START_FLAG_REDELIVERY – what prevents the following scenario?
onStartCommand()is called and the lock is acquired.- The system kills the service before completion.
- The system re-delivers the intent with
START_FLAG_REDELIVERY, causing anotheracquire()call on the already held lock. - The service completes and calls
release()once. - The reference counted lock is still held forever due to being acquired twice but released only once.
Your scenario implies that Android would terminate the service and leave a
WakeLockoutstanding. I am aware of no scenario under which this will occur. Android terminates processes, not services, and it is the OS’s responsibility to release any acquiredWakeLockat that point.As I noted in that issue, while
START_FLAG_REDELIVERYhas decent documentation,START_FLAG_RETRYdoes not. I have no idea when it will get used. I have no idea what the state of theWakeLockwill be based upon those undocumented causes. And so forth. It is far better to risk the occasional accidental sleep than it is to accidentally keep the CPU powered on indefinitely.