How to keep the application running without using partial wakelock - android

I have a single started service in my application which keeps my application alive.
I am downloading the data in a thread in my application(may take from 1 minute from 30 minute).
I want my application not to go in sleep state. I dont want to use the PARTIAL_WAKELOCK mechanism to keep the battery life long.
Here, The intention of having some PARTIAL_WAKELOCK like functionality not because of the service,
I want it just for few threads(tasks).
Can AlarmManager help?

I want my application not to go in sleep state.
Then use a WakeLock.
I dont want to use the PARTIAL_WAKELOCK mechanism to keep the battery life long.
You do not have a choice.
Here, The intention of having some PARTIAL_WAKELOCK like functionality not because of the service, I want it just for few threads(tasks).
A WakeLock does not affect a service. It does not affect a "few threads". It affects the device's CPU. The CPU is what goes to sleep, not your service, and not your threads. If you do not want the CPU to go to sleep, you must use a WakeLock.

Related

Android: When is WakeLock needed?

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.

Tips for reducing battery drain for android services?

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.

android monitoring apps

I would like to create an Android application with real-time monitoring functions. One monitoring function is to audit the audio flow. The other function is to interact with a peripheral sensor. These monitoring functions can be triggered by others.
Besides, in order to save power consumption, the audio function will be running in a polling mode, i.e. sleep for a certain amount of time and wake for a certain amount of time.
I am considering how to design the Android application.
Whether to design the audio function as a Service or an Activity?
The problem is if it is designed as an Activity, the audio function will be off if screen turns off after a period of time.
How to design the polling function? Use an AlarmManager or a inner-thread with Timer?
My goal is to save the power consumption as much as possible. Thanks.
I would recommend following
a) Use a Service. Activity is short lived entity (it works only while it's on the screen)
b) Make the service foreground (read this: http://developer.android.com/reference/android/app/Service.html#startForeground(int, android.app.Notification). This will decrease the chance that system will kill your service
c) In the service, start a thread and do everything you need in the thread.
d) If you want execute periodically, just do Thread.sleep() in the thread (when Thread sleeps it doesn't consume CPU cycles).
I believe c) and d) is preferable to AlarmManager.
Here is piece from documentation (http://developer.android.com/reference/android/app/AlarmManager.html) : "Note: The Alarm Manager is intended for cases where you want to have your application code run at a specific time, even if your application is not currently running. For normal timing operations (ticks, timeouts, etc) it is easier and much more efficient to use Handler."
Since your application running it's better to have some permanently running thread and execute something on it. Generally speaking Handler, HandlerThread, MessageQueue are just convenience classes for more complex message handling and scheduling. It looks like your case is quite simple and usual Thread should be enough.
Concurring with Victor, you definitely want to use a Service, and pin it into memory by calling startForeground()
However I suggest you look into utilizing the built in system Handler ; place your functionality in a Runnable and call mhandler.postDelayed(myRunnable, <some point in future>) ; this will allow the android framework to make the most of power management.
That's a service.
And you may want some extra robustness: the service can be killed and NOT restarted later, even being a foreground service. That will stop your monitoring.
Start your service from the UI. If you want the service to survive device reboot, also start it from a BroadcastReceiver for android.intent.action.BOOT_COMPLETED.
Create a thread in the service as described in other answers here.
Additionally, use Alarm Manager to periodically start your service again. Multiple startService() calls are OK. If already running, the service will keep running. But if it's been forgotten by the system, say, after a series of low resource conditions, it will be restarted now.
Schedule those alarms responsibly: to be a good citizen, set the absolutely minimal frequency. After all, Android had some good reasons to kill the service.
With some services, even more steps may be needed, but in this case this approach seems to be sufficient.

Does a Thread running from a service with wakelock require wakelock?

I want to run a thread to do some work in the background (from a service that acquired a wakelock). after my thread finish work then it will stop the service.
My concerns are :
1- Do i need to require a wakelock in the thread that was started in the service?
2- Can the system kill my thread while leaving my service running?
3- if 2 is the case how could i stop my service (can i give the service a timeout time that it will die after it)
WakeLocks are, as I understand applied to the Android component (e.g. service, activity, etc.) and all its associated threads. So you would not have to aquire a new wakelock in your thread. You could prove this by passing the aquired lock and calling isHeld from the started thread.
You should consider a partial wakelock, this will concern only keeping the CPU running, regardless of the screen or keyboard activity. Since this is a service I assume you don't care whether the screen stays on.
Note that it states here: 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.
Edit: Also, even though you can do it the way you suggested, it might be better to only aquire and release the wakelock in the child thread for battery consumption purposes. And if you are needing to use WiFi for this work a WiFiLock may also be required.

Service architecture, continuously running vs. wake up

I have an application that wakes up at frequent intervals (once per minute) to do some stuff in the background. I will be using the AlarmManager to schedule the wake ups.
I am looking at two different ways of structuring a Service to do the background work:
keep the service continuously running in the foreground with setForeground(). This is attractive since the application state will remain in memory between wake-ups.
use stopSelf() to destroy the Service after it has finished running the background task. This will require persisting some non-trivial objects between each wake up.
What are the pros and cons of each approach? How costly is persistence? What is the recommended approach for storage for case 2?
I will be using the AlarmManager to schedule the wake ups.
Hopefully not if you are going with option #1. If your service will be running all of the time anyway, just use Timer.
What are the pros and cons of each approach?
setForeground() doesn't work and hasn't for quite some time. startForeground() works, but it requires an active Notification.
A one-minute polling cycle is on the cusp of when I'd consider switching to AlarmManager and an IntentService. That being said, a one-minute polling cycle is awfully frequent. I strongly encourage you to make this user-configurable, including an option for "please don't poll, I'll request updates through the UI".
This will require persisting some non-trivial objects between each wake up.
You need to be persisting those objects in both cases. For example, when the user attacks your option #1 service with a task killer, it'd be nice if you did not lose their data.
How costly is persistence?
It does not really matter, since you need to be be persisting those objects in both cases.
What is the recommended approach for storage for case 2?
That is impossible to answer in the abstract.
You definently want to go with option 2 and stop your service once it's done. If you keep it running your going to keep using system resources, namely the battery. Do what you need to do, then stop the service. Also, what kind of wake up are you doing every minute? If you are doing a full-out device wake up (RTC_WAKEUP), you're once again going to kill the devices battery.
I hope this doesn't sound snooty, but I once heard a devloper say "Don't fight android, android will win". When you keep tyring to set your service to the foreground, you're fighting against androids attempts to clean up resources that aren't in use. You should instead embrace android. Do things as asynchronously as possible. That's the android way :)

Categories

Resources