Schedule time exact tasks in Android for a short interval - java

Application has running ForegroundService. While this service is running it needs to execute some tasks every 5 seconds. It's important to measure time interval in elapsed system time.
Handler.postDelayed
Timer
ScheduledExecutorService
Kotlin coroutines
RxJava
All of them work in uptime and affected by cpu sleep.
Official documentation recommends to use AlarmManager for time exact tasks, but for such short intervals it won't work and lead to "excessive wake up" warning.
Keeping wakelock preventing cpu sleep will cause severe battery use by app.
So my question is: how to schedule task which will be executed in a short time interval (few seconds), where time is measured on elapsed time timeline?
Thanks in advance for your help.

Related

How to stop/cancel a task in ScheduledExecutorService at particular time?

For example, I have a task which should be executed between 8:00-20:00 every minites every day.
so i calculate the time gap between 8:00 and the time which my app started for initialDelay, and use Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(command, initialDelay, 1, TimeUnit.MINUTE).
The question is, do I need the second timer to observe the task and cancel it when the clock comes to 20:00? or do I have to compare if the time is 20:00 at every time when the task's executed?
You probably need a real scheduler.
See Quartz https://quartz-scheduler.org
It should fit your needs
For the cron syntax : http://quartz-scheduler.org/api/2.2.0/org/quartz/CronTrigger.html
Or with a fluent API http://quartz-scheduler.org/api/2.2.0/org/quartz/TriggerBuilder.html

java.util.concurrent.ScheduledExecutorService runs very infrequent

I have a client application, where a runnable has to run in a fix period. Therefore I use the java.util.concurrent.ScheduledExecutorService as follows:
ScheduledExecutorService scheduledExecutorService =
Executors.newScheduledThreadPool(10);
ScheduledFuture scheduledFuture =
scheduledExecutorService.scheduleAtFixedRate(runnableClass,
period,period,TimeUnit.SECONDS);
As long as the workload is low, the task is scheduled in the defined period, i.e if the client receives no messages from the server. But if the server shoots out messages at full throttle, the runnableClass.run() is not executed on time. I feel like the time between the execution increases exponentially. But the Computer still runs smooth.
All Exceptions are catched inside run() and if I decrease the messages send from the server, the task is scheduled more often.
Why does that happen?
EDIT: The task needs a lot of resources and it is using Rserve to get predictions computed in R. There are probably up to 5000 calls to R in one task.
I made some tests regarding the time of the task. The task was always done in under a second, while the period was between 3 and 20 seconds.
How many threads are you running and how many cores do you have? Can it happen that you serve every request from a different thread, and the context switchings make your app run slower and slower?
Take care not to have much more CPU-bound threads than cores.
(Just a guess, sorry if it's way off)
Also, do you need a scheduled thread pool executor wit core size of 10? Isn't a SingleThreadScheduledExecutor enough for the scheduled task?

how to automatically run a java program every day at midnight when time changes from PM to Am

I want to run my program everyday at midnight when time changes from am to pm in between two dates, for example(from today date i.e 22/01/2015 to 25/01/2015).
There are many ways in doing this
ScheduledExecutorService, in built Java class you can use this it will schedule the job at specified time
Quartz FW is a 3rd party API to be use for large scale scheduling
Cron jobs, in linux and windows batch file you can do this
Autosys, job scheduler
As suggested by others, if you can, use ScheduledExecutorService.
If not, start a thread (Runnable or Thread) that runs your method m (which checks the date and time, and does the needful if time has changed from am to pm). Sleep for a few minutes, wake up, run m, ... let the process loop forever (or for as long as you want). Even better if you can sleep for the exact amount of time required so that when the thread wakes up, you know there has been a transition from am to pm. For instance, your program started up at 10:00 am, then you could compute that it would be pm in 2 hours (120 minutes) from now. So, just sleep for 120 minutes. Wake up and do the am-to-pm activity and sleep for 24 hours.
I would very much recommend a CRON job for this as it is reliable, and comes built in with most Linux environments if that's where you're running it from.

ScheduledExecutorService behavior on Android

I'm looking for Android specific implementation detail of ScheduledExecutorService.schedule when device is in deep sleep. I understand that schedule will not guarantee exact timing but simply execute "after" the delay. What I am not clear on is how sleep (and deep sleep?) is accounted in the timing. To be specific scenario:
Schedule a task an hour later
5mins in, the phone goes to sleep for 30mins
When do I expect the task to get scheduled?
Also if the phone wake up long after the scheduled time, is the task then scheduled for execution immediately?
As far as this post says Difference between AlarmManager and ScheduledExecutorService, it won't work in deep sleep mode. And I think it should be pretty simple to test it on an android device if you try to run a task after some arbitrary time and just wait for device to go in deep sleep mode.

Timer triggered unexpectedly in java

I have started timer with fixed rate. When user change system Time at that time task is executed continuously.It doesn't consider about the period time. How to manage this.
timer.scheduleAtFixedRate(task, delay, period);
Note : Now system time is current time.Period is 30 seconds. Now user change system time into after 10 mins from current time.At that time timer task not consider about the period. Within a second it execute the task 20 times.
When I use
timer.schedule(task, delay, period);
instead of
timer.scheduleAtFixedRate(task, delay, period);
task working normally. If I change system time to 10 mins past time from now task doesn't executed...
How to solve this ? :(
Have a look at this Stack Overflow answer; long story short, using scheduleAtFixedRate will queue up the tasks you have scheduled and fire them relative to the system time that the task was first queued; if anything should delay these tasks from firing, they will play 'catch up' and fire as fast as they can. So in your example of how changing the system time to +10 minutes made the event fire 20 times make since given that your period is 30 seconds (1m/2 = 30s, 10m*2 = 20 events).
Using the schedule function has similar issues, except it does not play 'catch up'; if you had a timer set to fire off every 30 seconds, then change the system time to +10 minutes only 10 seconds after the timer has started, your first event will trigger, then continue to wait the 30 second delay and fire again (unless you change the system clock again).
If you want something that is independent of system time you'll need monotonic clock values. To my knowledge the Java API does not directly contain any monotonic timers (for numerous reasons), but that doesn't stop you from implementing one yourself (albeit at the cost of possible wasted execution time in custom timer class code). Here's a Stack Overflow question regarding this, as well as a Google Group discussion post on it.
If you're really hard pressed for using a monotonic timer you could potentially use the POSIX API's and do some Java->C JNI work.
I hope that can help (at least point in a solid direction).

Categories