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.
Related
I am developing a flutter application, however I would like a service to be able to run constantly without stopping in order to make an api request every 15 minutes and then send a notification to the user (Android /IOS). I would also like the service to start automatically with the smartphone. I've been stuck on this for more than a week now and I've been browsing the forums looking for a solution but I can't find what I'm looking for. Thank you in advance for any help
You don't do it like that on Android. You cannot count on an application not being killed in the background. Instead, you use JobScheduler or WorkManager to set an alarm and wake you up every so often to perform whatever job you need. These methods can also ensure you're scheduled at startup of the phone.
Also, 15 minutes may or may not happen- Doze mode may cause your app to be delayed and make requests less frequently than that if the phone goes to sleep (although 15 minutes is fairly safe, plus or minus a few).
I'm working on an application in which I have to do some repeating task at fixed interval (let's say after 2 mins) which should complete even in doze mode. My observations are mentioned below -
Doing repeating task using Alarms (using RTC flag) aren't accurate. Android system batches alarms. If we use RTC_WAKEUP then it is better than RTC, but it shows WAKEUP count in Android Vitals which is not good.
Jobschedulers are useful but will not work for lesser interval like 2 mins. I had tried Firebase Jobdispatcher but that is also not very accurate, I started Job with 2 mins Trigger time but it was varying from 10-20 mins.
Used Handlers and Timers for repeating task in Foreground service. In this scenario Foreground service continue to run in Doze mode but handlers and timer stops repeating task. I read about Handlers.postDelayed() and found that this is also affected by doze mode.
I don't want to acquire WAKELOCK for this repeating task.
Can someone please suggest me some better/clean way by which we can do short interval repeating task in doze mode?
For reference -
Android: What is the best way to make repetitive Background Tasks Android Oreo ready?
How does doze mode affect background/foreground services, with/without partial/full wakelocks?
Not exactly a direct answer but still - I needed to schedule an action every minute in my foreground service (give or take a second).
Fortunately I was capturing sensors in this foreground service too, I made onSensorChanged event check if the right time has passed and act if needed.
Recently, I have been working on scheduling repeated tasks in background threads in Android application. I started with AlarmManager but due to its inaccurate triggers at specified intervals, I decided to use other JAVA and Android APIs.
I started with Timer and then ScheduledExecutorService and lastly ScheduledThreadPoolExecutor.
The problem with Timer is that it does not always run all the background tasks at right intervals. I had used it to run 3 background repeating tasks out of which only 2 were getting triggered. The third task was triggered after a couple of hours and to catch up with all the previous misses, it was triggered within 10ms (although the interval was 5 mins)
ScheduledThreadPoolExecutor is more accurate in triggering the repeated background tasks. But the problem with it is that it does not trigger the background tasks when the device is in sleep mode (screen off). The same is the behavior with Handler.postDelayed() which pauses the execution of tasks when the device is in sleep mode.
Now, I have reached a dead end. I am looking for a solution that could help me run my background tasks concurrently and without any interruption due to device going to sleep mode.
Please advice.
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"
I'm trying to run a background task which runs every minute or so for an android application but I am struggling to ensure that the task actually runs every minute. I've tried a variety of approaches from using SystemClock.sleep() to the AlarmManager (both repeating alarm and a fixed alarm) but it seems that unless the device is charging any kind of repeating system has a variable repeat rate once the device is unplugged. Is there any way to run a stable consistently repeating service?
Have you implemented Timer? It works very well for what I use it for, but then again I haven't worried about the precision at all. For all I know it may be varying a bit but I doubt it. It seems pretty consistent to me.
Edit: I am not liable for your responsible or irresponsible use of this facility ;)
If you need to have a service that runs every minute, on the minute, you have two options:
Use AlarmManager.setRepeating(RTC_WAKEUP, ...). In this case, the phone will sleep, but the RTC inside the phone will wake it up every minute to handle the repeating event. This will work, but will not be terribly exact as a lot of things are happening after the phone wakes up so your code might not get execution time right away.
Obtain a WakeLock from PowerManager and use whatever you want to time your code (Timer, Handler, etc.). This forces the phone to never sleep, which means that it is most likely free to run your code almost exactly when you request.
Both approaches will definitely drain the battery of the phone fast. Normally, the phone can sleep for 4 or even 9 minutes between wakes, so waking up once per minute is a big change from that.