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.
Related
We have a "chat" SDK for lack of a better term, designed to drop into a host application and allow live chat sessions with an agent. Part of that process is polling the server every few seconds while a conversation is taking place for new messages or information. Since this is intended at least partially as a diagnostic aid, it is very desirable that this polling and conversation continue in the background. Note that we have a defined start and end of a conversation, so this is not a boundless process.
Up until recently, this was implemented as a BoundService that was directly started (the conversation has to survive past being bound) With the changes to Android 8.0, this no longer works. The background service is terminated "shortly" after the application is put in the background.
My first attempt around it was to use a periodic JobScheduler, but that can't poll any more frequently than 15 min.
We're investigating options for supporting Android 8.0, and so far the easiest option seems to be to eliminate the background service and implement the polling using a CountDownTimer (more or less obviously on the main thread, but irrelevant because the work is actually handled in an AsyncTask) This seems to be working fine, the polling continues until the conversation ends and everything is copacetic.
Should I change this to use a JobScheduler with a short timeout that just reschedules itself upon completion?
Another option might be a foreground Service containing the conversation itself, but that would entail quite a bit more work.
If you need such short poll times, I would advise either you use the following
ScheduledThreadpoolExecutor
As per reading tour case, this seems the most suitable option as you need regular intervalic polling on a seperate thread. The ScheduledThreadpoolExecutor has a very easy implementation for this. Note the following code:
Executors.newScheduledThreadPool(10) //thread count
.scheduleAtFixedRate(() -> {
//Perform action; //Implement a runnable
},1000, 10, TimeUnit.MINUTES);
//1000 - The initial delay in milliseconds.
//10 - The number of minutes to keep polling.
All this happens on a separate thread, as you requested. Executors are a basic Java Framework Threading Primitive. The only downside is once the process is killed. The constant polling will die too.
For a more Android-Centric approach try an AlarmManager which can optionally survive process deaths even phone-reboots (only if you want, you must declare this in the manifest)
AlarmManager
This class provides access to the system alarm services. These allow you to schedule your application to be run at some point in the future. When an alarm goes off, the Intent that had been registered for it is broadcast by the system, automatically starting the target application if it is not already running.
Example Implementation
Calendar repeatTime = Calendar.getInstance();
repeatTime.set(Calendar.HOUR_OF_DAY,14);
repeatTime.set(Calendar.MINUTE,05);
AlarmManager mAlarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(mContext, <YOURBROADCASTRECEIVER>.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, YOUR_REQUEST_CODE,intent, PendingIntent.FLAG_UPDATE_CURRENT);
mAlarmManager.setInexactRepeating(AlarmManager.RTC,repeatTime.getTimeInMillis(),AlarmManager.INTERVAL_FIFTEEN_MINUTES, pendingIntent);
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.
I am making an app that needs to execute a function each hour even the app is closed.
First of all, I thought to create a service, but during my tests, I realise that android sometimes kills my service. So I was looking for another solution and I found AlarmManager. I have implemented it and it seems to work but I have the doubt if it will happen the same the service or it will run forever? (Until reboot of the mobile...)
Another question, it is necessary to create a new thread to execute the process in alarm manager or it runs directly in other thread?
I have implemented it and it seems to work but I have the doubt if it will happen the same the service or it will run forever? (Until reboot of the mobile...)
It will run until:
the device is rebooted, as you noted, or
the user uninstalls your app, or
you cancel the events yourself, or
the user goes into Settings, finds your app in the list of installed apps, taps on that entry, and clicks the Force Stop button
It's possible that alarms will need to be scheduled again after your app is upgraded (I forget...).
it is necessary to create a new thread to execute the process in alarm manager or it runs directly in other thread??
Unless the work you are going to do will take only a couple of milliseconds, you will want a background thread for it. That leads to two possible patterns:
If you are not using a _WAKEUP-style alarm, use a getService() PendingIntent to send control to an IntentService every hour
If you are using a _WAKEUP-style alarm, you will need to use a getBroadcast() PendingIntent, and have it either invoke your subclass of my WakefulIntentService, or you will need to manage a WakeLock yourself to keep the device awake while you do your bit of work
No, Android won't kill scheduled alarms and they got executed as planned unless app is replaced or device is rebooted. Use broadcast receivers for these events to reschedule Alarms. There's no way to prevent Force Stop as it kills all of your app components and threads totally.
That depends on what Alarm Manager do. If it sends a broadcast, the receiver limit is 10 second.
If it starts an Activity, Service or Intent Service, there is no limit. For Activity and Services you must finish or stop it and for Intent Services until the process is finished. Be aware that you can't have another thread inside Intent Service and you'r limited to code inside the OnHandleIntent.
Also you must consider device state. If it's sleep and you are using Wake Up flag receivers won't need a wake lock, but others do. It won't take long for device to go back to sleep.
Don't waste system resources with a service because Alarm Manager do what you want.
First time I have tried to implement either of these and I am unsure which to use.
I want my application to create a time frame, e.g. 2/3/12 to 7/3/12. Multiple time frames such as this can be created. A different intervals (e.g. every 4 hours) I would like my application to preform some actions for each time frame. This needs to be done in the background.
I have first tried to implement this with a Service, but am having performing all the actions for each of the time frames concurrently. After reading the android blog "Multitasking the android way" I think that perhaps BroadcastReceivers are better.
Please advise
Please see my answer about using the AlarmManager - Running task periodicaly(once a day/once a week)
If you are only running a process at a set time rather than constantly (e.g. monitoring audio levels) then you are going to ask a service to sit there 90% of the time and do nothing except waste battery power. The AlarmManager solves this problem as it notifies the broadcast receiver to execute at the given times.
Edit: Also bear in mind that after phone restart all alarms are removed so you will need to register a broadcast receiver to be notified of the device boot-up so you can re-register any Alarms that are needed.
You should probably be using the AlarmManager and a IntentService.
The AlarmManager will kick of your IntentService at specified intervals. You can kick off the IntentService for each set of actions.
I need to run a background service in Android mobile which runs 24*7, And on Start & On mobile low battery and Hit a webservice every 1hr. Can you please suggest me any approach. I tried reading few articles but did not get any idea. I know here I need to paste some code after trying something. But I did not get any clue. Please let me know how to approach?
You will probably need to use the method startForeground(int id, Notification notification) to prevent the system from killing your Service as stated here:
A started service can use the startForeground(int, Notification) API to put the service in a foreground state, where the system considers it to be something the user is actively aware of and thus not a candidate for killing when low on memory. (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.)
Then you would need some kind of scheduled task to run every hour. Something like a ScheduledThreadPoolExecutor is ideal for this purpose, using the method scheduleAtFixedRate (Runnable command, long initialDelay, long period, TimeUnit unit).
The task that needs to be done each hour must be implemented as a Runnable and submitted to your ScheduledThreadPoolExecutor:
ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor( 1 );
executor.scheduleAtFixedRate( new MyRunnableTask(), 0, 1, TimeUnit.HOURS );
The Runnable task should be something like:
private class MyRunnableTask implements Runnable {
public void run() {
//Do what needs to be done.
}
I need to run a background service in Android mobile which runs 24*7
Please don't. For starters, it is not possible.
Users complain loudly and often about services that "run 24*7", because the services are tying up system resources (e.g., RAM) for no value. As a result, between third-party task killers and Force Stop options in Settings, users get rid of such services. When they do, particularly on Android 3.1+, your application will not run again, ever until the user manually launches an activity of yours from the launcher.
Android itself will get rid of such services on its own, because too many developers are too sloppy with their service management.
And on Start & On mobile low battery and Hit a webservice every 1hr.
Based on this list, you do not need "a background service in Android mobile which runs 24*7". You need to do work:
when the device starts up
when the device's battery is low
every hour
You can find out when the device starts up by the ACTION_BOOT_COMPLETED broadcast Intent. You can find out when the device's battery is low via the ACTION_BATTERY_LOW broadcast Intent. You can find out when time elapses via AlarmManager, where you establish your own alarm schedule (e.g., every hour).
All three of these triggers should call startService() on an IntentService. The IntentService will allow you to "Hit a Webservice" via its built-in background thread. And, the IntentService goes away when that work is complete, so you are not taking up memory all of the time.
And, if you want to wake up the device out of sleep mode for the every-hour condition, you will probably need to use something like my WakefulIntentService, as otherwise the device may fall back asleep while you are trying to "Hit a Webservice".
This way, your service is only running and taking up resources while it is actively delivering value to the user. It is not running and taking up resources when it is simply waiting for some other event to occur (e.g., the next 59 minutes).