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.
Related
I am trying to schedule a job service when i receive BOOT_COMPLETED. Job is getting scheduled immediately and again getting scheduled periodically.
Here depending on some local criteria some time i need to delay the scheduling of job so i can call scheduleJob of scheduler after this delay.
My app does not have any UI and always runs in background , to provide delay i tried timer task , handler etc but these only worked in foreground conditions.
As my app is running in background these did not helped me .
I again tried starting intent service as foreground service and in onHandleIntent trying to sleep the thread for specified time.Once sleep time is over i am scheduling the job and stopForgroundService . Max delay i need to handle is 24 hours.
Is this correct approach to provide delay of max 24 hours and hold it using foreground service or is there any other way i can achieve this.
IntentService, TimerTask
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.
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 have an app that writes some data to a file every second.
I used a Timer that and schedule it at a fixed interval of 1000
for the most part it works fine, but sometimes i notice there are seconds, or sometime even minutes where there is no data in the log file.
Is there any likely suspects to this problem?
Timer runs in background thread(s) that are not reliable. From the docs:
Each timer has one thread on which tasks are executed sequentially. When this thread is busy running a task, runnable tasks may be subject to delays.
LINK: http://developer.android.com/reference/java/util/Timer.html
If you have a time sensitive task, then you need to check SystemClock like here:
How to measure elapsed time
I'm making an app that starts a Service that sends SMS message periodically under specific conditions. It all works, but I have problems to run the job (check conditions + message sending) periodically every minute when the phone is in "standby" (display turned off). With screen on it all works without problems.
I tried using java Timer and TimerTask, but when the screen is off nothing works and when I turn it on, all skipped task are executed in a row (for example, if I turn off the screen at 20:00 and turn on it at 20:30, TimerTask is executed 30 times at 20:30).
I tried also with Handler using Handler.postDelayed method. In this case nothing is done, and when I turn on the screen skipped task are not executed.
So, how can I run a Runnable every minute also when device screen is off???
You can try the AlarmManager
http://developer.android.com/reference/android/app/AlarmManager.html