My Application needs to have one (async) task which is always a network operation and the first time a DB query as well.
It needs to be executed with a certain interval amount of time which is not fixed (could be 1 minute or 1 hour or anything in between) and also when the application is not active.
What is the best and the simplest solution in such case between Asynctask/Thread/Service/Alarm/anything not mentioned.
For that you need a service, not an AsyncTask:
http://www.vogella.com/tutorials/AndroidServices/article.html
Services persist even after activities are dismissed. Be careful though, draining the battery will anger your users. Also, services can be destroyed if memory runs low, so be careful.
The scheduling of a task to run in the future should use AlarmManager. The execution of the operation should run in a service since you specify that sometimes it will occur when the app is not active.
You can also use a TimerTask but it's a little more drain on battery and not as precise as AlarmManager. You can also use a handler to postAtTime
Here is a good reference:
difference between timer and alarmmanager
and another one:
What is better in Android? Timer or Alarm?
It really depends on the frequency and use-case. I've used all of these - I view TimerTasks as "keep checking frequently for short time" vs. handlers for "check again in a while" vs. AlarmManager for "I want to keep checking every hour for a long while"
Related
I have gone through various discussion threads and tried multiple iterations to have my application scheduled to repeatedly run at fixed intervals. I have been successful too, but starting the thread to get understanding how things work.
I had tried the implementation with ScheduledExecutorService as well as TimerTask and both did not trigger my task at right intervals. But found success with AlarmManager.
Please lead me in right direction to understand why the timing did not work well with ScheduledExecutorService and TimerTask.
The app is required to perform a task on a regular interval. Say, my task takes around 5 minutes to complete, I would like to keep it scheduled so that it runs once in every 30 minutes. When I built the application with ScheduledExecutorService or TimerTask, I found that it does not trigger the task at 30 minutes, but it triggered at 1 hour or even more. So far, with Alarm Manager, it seems to be working fine getting triggered at around 30 minutes(slight variation is still found, but better than the other two).
When I built the application with ScheduledExecutorService or TimerTask, I found that it does not trigger the task at 30 minutes, but it triggered at 1 hour or even more.
More importantly, it will not trigger at all once your process is terminated, which can happen at any point and, from the user's standpoint, should happen quickly, to free up RAM for other apps.
Your trigger delays are probably due to the device falling asleep. Your solution would not only tie up the user's RAM, but also would require you to prevent the device from falling asleep, which is horrible for battery life.
AlarmManager is a far more appropriate solution, as it does not require you to keep a service running or otherwise have a process around. Just be sure to use WakefulBroadcastReceiver as the way you respond to your _WAKEUP event, as the device will want to fall back asleep.
I am working on an application which triggers an action (say toast message) every 10 minutes after the screen is ON and stops the action after the screen is OFF.
I have used TimerTask for this purpose.
Shall I start using AlaramManager instead of TimerTask or shall I keep using TimerTask ?
I know the difference between the two but can't figure out which to use.
Cant' agree with the nikis' answer
Timer and AlarmManager are solutions addressed to satisfy different needs.
Timer is still a "task" that means this is a thread of your application that means that some component of your application must be running on device to keep timer alive.
If you set timer for 10 minutes events - you can't be sure if your application will not be disposed by system in some moment. If device will be turned into the sleep mode your timer can be stopped. To prevent behavior like that you have to use PowerLock's and drain battery
AlarmManager is system service (runs outside your application) that means that the pending intent will be sent even if your application is killed after setting the alarm.
Some examples:
You have to blink some "led" on the view every 1 s - use Timer - you need it only when application is in foreground, there are short intervals - no point in using AlarmManager for task like that.
You have run some task once after 10 s - Handler.postDelay(); will be the best solution for that, and the job will be done on main thread (UI).
You have to check every 10 minutes if there is some new content on device that you are supposed to push to the server - use AlarmManager - your application does not need to be alive all the time, just let system to start job you want every 10 minutes - that's all.
In most cases you should definitely use AlarmManager, because (from the docs):
The AlarmManager holds a CPU wake lock as long as the alarm receiver's onReceive() method is executing. This guarantees that the phone will not sleep until you have finished handling the broadcast. Once onReceive() returns, the AlarmManager releases this wake lock. This means that the phone will in some cases sleep as soon as your onReceive() method completes.
Although you don't need to fire any event while screen is off, AlarmManager still saves the battery by grouping alarms, when you use setInexactRepeating (but this is not important for you, because your interval is 10 minutes). And moreover, it can fire an event is app is not running. I vote for AlarmManager, because it's good practice, but considering your conditions, you can leave Timertask.
BTW, you can also use Handler, which I believe will be the best choice.
Are there any major differences between CountDownTimer and AlarmManager? I don't mean syntax or how to use it but wondering if there are such tasks when you certainly can say that I should use one of them, not another?
Simple example, I have to launch some action once a minute. What should I use? CountDownTimer or AlarmManager? How it depends?
AlarmManager generally is used for purposes where your application is closed or must execute some repeating task(s). It is also slightly less precise than Timer or Handler.
CountDownTimer is used more for running a specific task at a duration (onFinish), and being updated periodically until it executes (onTick).
In your specific case, I believe you should be using AlarmManager, since it can repeat indefinitely. If you want something to execute every second for 10 seconds, for example, use CountDownTimer.
CountDownTimer
CountDownTimer will run in the context of your Activity. means It can be killed at any time, If your app is not on forground.
AlarmManager
A total different approach uses Sticky Intents. And tells your Receiver, after some time. It does not depends on the Activity's life Cycle.
So if you want to do some operation every minute, even your app is not on forground then you should use AlarmManager, otherwise CountDownTimer will do the job for you.
As described here :
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.
So in your case is better to use CountDownTimer, since you don't want to do the action even if the app is closed.
Besides setting and exact time (i.e. midnight) versus setting a delay (i.e. 24 hours), what's the difference between using AlarmManager and ScheduledExecutorService to run a task periodically?
In my case, I need to run a little bit of code to check for new data every night and create a new notification if there is new data.
Thanks!
ScheduledExecutorService runs in your application process. If application process dies, none of the scheduled tasks will run. Hence the need for Service (so your process lives beyond Activities active part of lifecycle).
While AlarmManager is critical system service that runs all the time. And if your application scheduled something and was killed, then AlarmManager may start application again (via PendingIntent).
And the last major difference that no one mentioned here is that AlarmManager knows about WakeLocks and power management. This means that AlarmManager may wake up Android device at specified time to run scheduled task. While ScheduledExecutorService knows nothing about power management and will only start task when device is not in deep sleep (i.e. it can simply miss the time).
ScheduledExecutorService will only work if you have some component, such as a Service, running all of the time. Hence, it should only be used in cases where the component would be in memory for other reasons, adding value to the user. Having a component be in memory solely to watch the clock tick by is wasteful and one of the reasons why users attack developers with task killers and such.
AlarmManager is an OS-supplied system service. It can start up a component when the time rolls around. Hence, you do not need to have the component running.
In my case, I need to run a little bit of code to check for new data every night and create a new notification if there is new data.
This is a clear scenario for AlarmManager.
I think ScheduledExecutorService is tied to your process and will not work in case your process gets killed. In contrast AlarmManager is managed by the OS so it works even if your application is not running.
Would it be better to have a service that is continually running a timer and executing a task every five seconds. Or would it be more efficient to have an alarm manager starting the service every five seconds? How about every second? I'm interested to hear your responses. Thanks!
According to the AlarmManager documentation, it's only for cases where you want to run at a specific time. For what you're talking about, you'll want to use a Handler, with postDelayed().
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.