Is Android's Wakelock a necessity for background services?
Asked Answered
D

1

8

I am writing a long-running background service that collects and analyzes device data. To do this I start a service, the service spawns a thread and the thread does the data collection / analysis.

From my reading I have learned that if I want the service to do it's thing while the screen is locked / device is sleeping, that I should be using a partial wakelock to ensure that the cpu does not go to sleep while the service's thread is running. However I'm really confused about this because I am currently not using a wakelock and am able to background my app or lock the screen or kill the app via the task manager and each time I do this I am able to observe via the logcat and Log statements that the thread that I spawned in the service is still running and doing the work that I want it to.

I've even run an adb shell dumpsys power and found that I have refcount = 0 for wakelocks which indicates to me that a different app isn't holding the wakelock for me.

Am I just getting lucky that my service seems to run just fine in the background without a wakelock?

Edit: The device has exhibited this behavior when connected to USB and when detached from USB. I have am periodically uploading the data that I collect to a server and have run tests where I never plug the device in and have the screen locked the entire test and I still am seeing that my thread runs and data gets uploaded.

Draggle answered 4/5, 2015 at 5:44 Comment(2)
Are you doing this with your USB cable attached?Haemato
@addy2012 I have seen this behavior while connected to USB and detached from USB.Draggle
P
4

You were not "lucky" that your service is fine without a wakelock. Your device never slept.

If you have USB connected and supplying power, then your device will not sleep. After all, what is the point of saving power if you have a ready supply of it to use?

You need to connect to your device using adb over IP (adb connect ) and then do logcat from there to see if you still observe your expected logs.

EDIT: Forgot to actually answer the question.

If you want your service to do things constantly, then you need to keep a wakelock. Keep in mind that permanently keeping a wakelock is basically sin #1 in mobile programming. You should NEVER EVER KEEP A PERMANENT WAKELOCK.

Since your service is tracking data usage, then there is no need for a wakelock since, if the device is sleeping, then there is no data to be logged.

EDIT 2: Let's experiment!

Hmmm. Sleep is hard to force, so let's go straight to the nuclear option.

  1. Modify your code so that instead of actually uploading data, you instead store some meta-data to tell you that you would have stored data at a specific timestamp. Also, modify your code so that you can keep track of power events and also timestamp them. If you can, keep all of this data in memory so that we don't have too much system code running.

  2. Put your phone into airplane mode. That's right, turn off all external connections. Also, don't use ADB or logcat or anything like that.

  3. Kill all non-essential apps. Uninstall is best.

  4. Run your service as a user would using the UI. DO NOT USE A TEST OF ANY SORT; TESTS MAY PREVENT SLEEP (it's hard to know anything for certain on Android since sleepiness is an OEM thing).

  5. Wait a while.

  6. Dump out your in-memory logs with timestamps. You probably won't get accurate data on when the sleep occurred, if it will even tell you that you slept. But you should be able to infer it from odd power event orderings as you transition back to the state that you were just in.

Pansophy answered 4/5, 2015 at 6:6 Comment(4)
I edited my question to include more information. I am seeing this behavior whether or not I am attached to USB. I have run tests for an entire day before where the device is sitting on a table, not plugged into anything with the screen off. My background service starts and uploads data as expected for as long as the device has battery. (But thanks for the tip about USB I hadn't thought of that as possibly confounding my results).Draggle
Edited my answer with an experiment that you might try. At this point, it could be an OEM bug or something that you're doing which is preventing the system from thinking that it is in a sleep-able state. Sleep is complicated because almost all of the "can I sleep?" inputs are invisible to the user. Besides the obvious ones, of course.Pansophy
I ended up doing a long-running test where I attempted to run a service while the phone was unplugged and the screen locked and upload the data every minute. What I found was that over a 48 hour period sometimes the device would behave how I intended (upload every minute) and other times it would wait for an hour before uploading. This confirmed that I definitely to need a wakelock to achieve consistent performance, however it was confusing because it wasn't all or nothing, it was intermittent and difficult to diagnose that there was actually something wrong.Draggle
Such is android sleep state :/. Glad to see that you figured it out.Pansophy

© 2022 - 2024 — McMap. All rights reserved.