The rules for holding cpu partial wake locks are very vague. Can someone explain when and why we should acquire one? When can the system decide the service should be suspended while doing some work on a thread?
I would like to understand the details of the cpu scheduler / activity / service manager.
Is the best place the android source code? if so which package?
Can someone explain when and why we should acquire one?
You acquire one when you need the CPU to stay running to complete some bit of work. You release it when that work is done.
So, for example, suppose you have an IntentService triggered by AlarmManager. You want the IntentService to check for new email messages for your email client. You would want to acquire a WakeLock so the CPU will not fall asleep while you are in the middle of doing that, then ensure that you release it. This sort of pattern is why I created the WakefulIntentService.
When can the system decide the service should be suspended while doing some work on a thread?
The fact that you are doing "some work on a thread" is immaterial. The CPU will fall asleep based on user inactivity. If the user is not keeping the device awake, and you are not keeping the device awake with a WakeLock, the device will fall asleep.
Having the CPU fall asleep is very important for power consumption. If you, say, decide that you are going to keep the CPU running 24x7, the battery will run dry relatively quickly.
Related
If I have an IntentService that simply updates the SharedPreference, is a (partial) WakeLock needed?
I understand that a WakeLock keeps the CPU awake, but when is it needed?
If you need to keep the CPU running in order to complete some work before the device goes to sleep, you can use a PowerManager system service feature called wake locks. Wake locks allow your application to control the power state of the host device.
Creating and holding wake locks can have a dramatic impact on the host device's battery life. Thus you should use wake locks only when strictly necessary and hold them for as short a time as possible. For example, you should never need to use a wake lock in an activity.
One legitimate case for using a wake lock might be a background service that needs to grab a wake lock to keep the CPU running to do work while the screen is off. Again, though, this practice should be minimized because of its impact on battery life.
Unfortunately, some poorly-coded, malicious, or simply buggy apps might create an abnormal amount of undesirable wakelocks. Other apps require constant Internet access in order to operate in a normal fashion - Facebook and Messenger are probably the most popular representatives. They persistently request information from the web (the so-called "polling" for new events), which is causing subsequent wakelocks.
In other cases, an update to a given app can also cause certain issues, which usually result in partial wakelocks. The latter keep your CPU constantly humming in the background, sometimes without your knowledge, and prevent your device from "going to sleep". That's a pretty substantial prerequisite for anomalous battery drain. Thus, it is advisable to regularly monitor the wakelocks on your device and see which of your apps go harsh on our system's resources.
Read more at:
What-are-wakelocks-how-they-affect-the-battery-life-of-your-Android-device-and-how-to-Greenify
Reference: https://developer.android.com/training/scheduling/wakelock.html
It is needed when you don't want CPU to sleep when user locks the screen for example.
If you have an IntentService without acquired WakeLock it will pause after a while if user locks the screen and it will continue its work when user wakes a device. With WakeLock acquired your service will work even if the screen is locked.
As #My God mentioned, it impacts on battery life a lot, so, use it only when you really need to finish some operation and you cannot wait till user wakes a device.
I wrote an app recently and, well I'm quite disappointed about how much battery the service consumes. I go to make a call yesterday to find my battery is at 9%; I check the android system statics for the battery and find that my app is responsible for 60% of the battery drainage
My question is, what can one do to reduce the battery usage on an app that runs and then sleeps for 60 seconds? The service is reading from a SQLite database; I could cache the data, but would that really account for that much battery usage? What are some standard ways to reduce battery drainage in a service?
You should look into using AlarmManager to schedule your app or service to be called when necessary. This has a big advantage over your current wake lock method, because even a partial wake lock will keep the CPU running. An AlarmManager alarm can wake the phone even from CPU sleep.
Basically, get rid of your existing wake lock and schedule an AlarmManager alarm—which can repeat once a minute, if that's what you need—to wake up the device, if necessary, and send you a message.
The AlarmManager itself will take out a wake lock while calling an onReceive() method to notify you of the alarm, and relinquish it when onReceive() finishes, letting the phone go back into deep sleep if it wants to.
Note that this means that if you want to do extended work—e.g. firing something off on a background thread—you'll probably want to take your own wake lock out in onReceive() and relinquish it when your work is done, otherwise the phone may go to sleep while you're in the middle of the work.
This is all pretty well-explained in the AlarmManager docs, but the best explanation I've seen is in Mark Murphy's The Busy Coder's Guide to Android Development; he also provides a library for exactly this pattern on Github. Definitely worth a look.
I think this is pretty much the standard case already described in other SO question but I still need a clarification on this matter:
So I have an Android app with an Actvity and a Service. The Activity is not of interest but the Service. The Service has to send some message to a remote server every minute. From what I understand, I need to use WakeLocks to keep the CPU running while allowing the screen to go off (so that I can fix the problem where the service stops when the screen is powered off). So far so good.
My question is: can I acquire the lock, send the message to the server, release the lock AND acquire it again after one minute so that during this one minute pause the CPU is sleeping, too. With the ultimate goal to save the battery. I fear the answer is "no" because once you let the CPU to sleep, you cannot wake it up unless from a lower level (OS and not app).
Best regards
The response is simple: no. What you can do in this case is set a PendingIntent and use the Android Alarm manager to be woken up every minute.
The alarm manager is the way to go - but you also need to delegate from the alarm receiver to a WakefulIntentService to do the work (as the receiver will ANR after 5 seconds). See PowerManager.PARTIAL_WAKE_LOCK android for links.
I am currently developing an app that runs a service from time to time. Currently, the service acquires a wakelock, reads some sensors and sends some information over WIFI (if any). Now what I want to know is weather a wakelock influences sensors and connectivity or not. Is it possible to do these tasks without any wakelock?
Cheers
A wake lock is essentially used to lock the device in an "awake" state, in which the CPU will be on, and the screen may or may not be on.
It is not possible to do these tasks without a wakelock if the phone is in sleep otherwise, as then the CPU is also in sleep mode. However, if the user is using the device for something else, and your app is in the background, you can do these tasks without a wakelock.
Keep in mind that almost everything you're doing is battery intensive (sensors, WiFi, wakelock) and you should not do it too often so that you don't degrade the user's battery life.
I know foreground services have "unlikely to kill" behavior. According to Android documentation:
It is still theoretically possible for the service to be killed under
extreme memory pressure from the current foreground application, but
in practice this should not be a concern.
I think this solves the low memory concern for most cases. But I cannot find any documentation on whether the CPU goes to sleep while a foreground service is running.
Does a foreground service automatically acquire PARTIAL_WAKE_LOCK or one has to call it explicitly if needed?
Is there any way to check/log which application/services are using PARTIAL_WAKE_LOCK?
Android foreground service and PARTIAL_WAKE_LOCK have nothing to do with each other.
Foreground service -> it tells the OS to put your service in the highest priority queue. If OS needs memory for any reason, it will kill your service at LAST, and it will start with queue at lowest priority (I believe there are 5 priority queues, and foreground is the highest).
PARTIAL_WAKE_LOCK -> it tell the OS not to put the CPU to sleep when device goes to sleep (whenever this happen).
So, even if you have a foreground service, if device goes to sleep the cpu might go to sleep as well (it might not if some other app acquired a PARTIAL_WAKE_LOCK).
I don't think there is a way to check which applications acquired wake lock programmatically, but you can plug your device to DDMS and you will see PowerManager logs when someone acquires a wake_lock.
Hope it helps !