I'm designing an app that has a recurring task of sending presence to a dedicated server as long as the app is in foreground.
In my searches across the web I saw a few different approaches and wanted to know what is the best way of doing this.
What is the best way to schedule a server call?
The options I saw were:
Timer .
BroadcastReciever with AlarmManager.
What's your opinion?
EDIT:
The reason I need this is for a chat based app that sends all the user actions to a remote server.
i.e. user is typing a message, user is reading a message, user is online, user is offline etc.
This means that once every interval, I need to send the server what I'm doing, since I open a chat room with other people, they need to know what I'm doing.
Similar to the whatsapp message feedback mechanism:
EDIT #2:
Recurring tasks should now be scheduled almost always via the JobScheduler
API (or FirebaseJobDispatcher
for lower APIs) in order to prevent battery draining issues as can be read in the vitals section of the Android training
I realize this is an old question and has been answered but this could help someone. In your
activity
In
onCreate
I am not sure but as per my knowledge I share my views. I always accept best answer if I am wrong .
Alarm Manager
The Alarm Manager 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. OnceonReceive()
returns, the Alarm Manager releases this wake lock. This means that the phone will in some cases sleep as soon as youronReceive()
method completes. If your alarm receiver calledContext.startService()
, it is possible that the phone will sleep before the requested service is launched. To prevent this, yourBroadcastReceiver
andService
will need to implement a separate wake lock policy to ensure that the phone continues running until the service becomes available.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.
Timer
Timer
has some drawbacks that are solved byScheduledThreadPoolExecutor
. So it's not the best choiceScheduledThreadPoolExecutor.
You can use
java.util.Timer
orScheduledThreadPoolExecutor
(preferred) to schedule an action to occur at regular intervals on a background thread.Here is a sample using the latter:
So I preferred
ScheduledExecutorService
But Also think about that if the updates will occur while your application is running, you can use a
Timer
, as suggested in other answers, or the newerScheduledThreadPoolExecutor
. If your application will update even when it is not running, you should go with theAlarmManager
.Take note that if you plan on updating when your application is turned off, once every ten minutes is quite frequent, and thus possibly a bit too power consuming.
Maybe it's not answer for your question, but advice for the structure of your aplication. As for me it's much easier to use node JS with SOCKET.IO for applications like chat. And as it's real-time, you don't need to ask server every certain time. There you can read more about SOCET IO -- http://socket.io/
Timer
As mentioned on the javadocs you are better off using a ScheduledThreadPoolExecutor.
ScheduledThreadPoolExecutor
Use this class when your use case requires multiple worker threads and the sleep interval is small. How small ? Well, I'd say about 15 minutes. The
AlarmManager
starts schedule intervals at this time and it seems to suggest that for smaller sleep intervals this class can be used. I do not have data to back the last statement. It is a hunch.Service
Your service can be closed any time by the VM. Do not use services for recurring tasks. A recurring task can start a service, which is another matter entirely.
BroadcastReciever with AlarmManager
For longer sleep intervals (>15 minutes), this is the way to go.
AlarmManager
already has constants (AlarmManager.INTERVAL_DAY
) suggesting that it can trigger tasks several days after it has initially been scheduled. It can also wake up the CPU to run your code.You should use one of those solutions based on your timing and worker thread needs.
Quoting the Scheduling Repeating Alarms - Understand the Trade-offs docs:
So, based on this, the best way to schedule a server call is using Google Cloud Messaging (GCM) in conjunction with sync adapter.
I have created on time task in which the task which user wants to repeat, add in the Custom TimeTask run() method. it is successfully reoccurring.
}