java.util.Timer SystemTime effect? - java

Said now is 6 o'clock, I have a Timer and scheduled a TimerTask at 10 o'clock. After that, System DateTime is adjusted by an other service (ntp for example) to 9 o'clock. I still want my TimerTask will be fired at 10 o'clock but it does not, Timer still wait for next 4 hours and fire my TimerTask. What should I do in this situation?

Firstly, you're already in a pretty nasty mess if your clock is out by 4 hours. Typically time adjustments will only be by milliseconds or seconds - or occasionally a minute or two, if the machine hasn't been online for a very long time. One option would be to check that the time is reasonably accurate by making your own NTP call before setting the timer.
Another option is to make a reasonably regularly-invoked timer - for example once every minute or five minutes - which checks the time and then optionally takes action. It's slightly less efficient, but I wouldn't expect the impact of waking up a single thread to perform a simple check once a minute or so would have a significant effect on performance. You should adjust the regularity of the check based on how accurately you need your timer to fire, and how little performance impact you need it to have.

Related

What happens with running timers when a system time is changed?

What happens with running timers when a system time is changed?
I have an android application and I use handler.postDelayed(Runnable,interval) to post a Runnable to be called (the run() method) at the end of the interval.
The question I have is:
What happens if the underlying system time is changed externally?
My impression is that the posting still happens but at the time of system time change the countdown starts again... Can anybody shade some light here?
Does the behavior change if the time change is forwards or backwards?
First,you should know Handler is based on SystemClock.uptimeMillis().
Handlers sendMessageXXX() methods such as sendMessageDelayed、sendEmptyMessage all use the method below internal:
//calcute the milliseconds we hope to handle the message since the system was booted
sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis)
Then,the time interval value SystemClock.uptimeMillis() + delayMillis will be kept into Message's field when,and we put the message into the MessageQueue waiting for Looper to poll out it.
While the looper gets the next message from the queue,it will compare SystemClock.uptimeMillis() with msg.when to judge whether the message is ready.If the next message isnt ready,it will set a timeout to wake up until the msg is ready.
Second,you confuse SystemClock.uptimeMillis() with System.currentTimeMillis().Below is part of the documentation of SystemClock which explains the two concepts:
SystemClock.uptimeMillis() is counted in milliseconds since the system was booted. This clock stops when the system enters deep sleep (CPU off, display dark, device waiting for external input), but is not affected by clock scaling, idle, or other power saving mechanisms. This is the basis for most interval timing such as Thread.sleep(millls), Object.wait(millis), and System.nanoTime(). This clock is guaranteed to be monotonic, and is suitable for interval timing when the interval does not span device sleep.
System.currentTimeMillis() is the standard "wall" clock (time and date) expressing milliseconds since the epoch. The wall clock can be set by the user or the phone network (see setCurrentTimeMillis(long)), so the time may jump backwards or forwards unpredictably. This clock should only be used when correspondence with real-world dates and times is important, such as in a calendar or alarm clock application. Interval or elapsed time measurements should use a different clock. If you are using System.currentTimeMillis(), consider listening to the ACTION_TIME_TICK, ACTION_TIME_CHANGED and ACTION_TIMEZONE_CHANGED Intent broadcasts to find out when the time changes.
No it doesn't matter. If you dig around the code, the delay is provided by the following mechanism -
SystemClock.uptimeMillis() + delayMillis
So it is purely relative. And changing of system time has no effect on it

Thread vs AlarmManager which one has low battery usage

What I need in my application is do some stuff every 30 sec for 18 hours per day which I want to keep running even device going to sleep mode
for that I found two ways:
Using timer using the AlarmManager with a type of AlarmManager.ELAPSED_REALTIME_WAKEUP
Using a thread with a unfinished while-loop and sleep for thread every 30 seconds.
Now I am using timers, that works fine in all API versions but have one problem and that's battery usage.
My question is, can I use a thread instead of timers? I heard somewhere threads cannot run for very long times (5sec max), but I'm not sure.
And if I can use thread, is that take lower power than timers?
and works for all API versions?
Here is a very good description of your question
http://www.vogella.com/tutorials/AndroidTaskScheduling/article.html

Java timer task: Adjusting daylight saving time

I have a piece of code that has to be executed at a particular time every day. If I schedule it to be executed at 9PM everyday, then it has to work even during the switching of Day light saving.
Which Java API can be used to achieve this?
int ONE_DAY = 1000 * 60 * 60 * 24;
Timer timer = new Timer();
timer.schedule(myTimerTask, startTime, ONE_DAY); // startTime is 9PM of current day
I've used the above approach which will not take care of DST.
If you need to schedule based on calendrical values - rather than just elapsed time, basically - then you either need to wrap Timer in your own code, or use a library which has already been built for this purpose. In this case, I suspect the Quartz Scheduler is your best bet.
Given how complicated date/time can be, I'd generally recommend using a well-known library over rolling your own code. Note that this often doesn't mean that you can get away without thinking about complicated aspects of the problem - it just means that you should be able to express your requirements fairly simply. For example, in the context you're looking at, you should consider:
What time zone do you want the "9pm" to be expressed in? Is it the system default time zone? Some other specific one? Multiple different time zones for different tasks?
What do you want to happen if the scheduled time doesn't occur, or occurs twice on one day? You're likely to be okay with 9pm, but if you had (say) 1.30am in the UK time zone, when the clocks go forward into BST, that will be skipped for that day - and when the clocks go back into GMT, it will occur twice.
How do you want to handle the system clock being changed, either manually or automatically?
You can schedule the timer to run the task each hour and let the task decide when to actually run using Calendar

Preventing timer manipulation from end user with android TimerTask and Timer

How can one ensure that a task that is supposed to run for x amount of time on an android os be run for that x period without user manipulation of date and time? For example, if I want this timer to run for 24 hours solid and then advise the user that 24h has passed, even if the phone is off for an hour, the user then turns it back on and sets the system time forward 2 hours, this timer would still indicate when that solid 24 hour period had passed without the user manipulating the system date/time and without connecting to the internet to verify the proper amount of time has passed.
Thanks
Here is flow/algorithm.
1) You need to store time of timer first initiated some where, probably database and let timer run for 24 hours.
a) assuming phone not turned off, timer continues
b) Assuming phone turned off and turned on
b1) Get initial timer started time from database, then calculate how much time left for 24 hours.
b2) Initiate timer again with left time.

Sleeping till NEXT Second

I am finding often the need to very often wait until the next second to do the next operation in a series. This slows down unit tests quite considerably. So here's my question:
Instead of doing Thread.sleep(1000) is there a quicker more efficient way to sleep until the second changes to the next second?
Say the time is 1:00:89
I sleep one second to 1:01:89
I would rather continuing executing when the time hits 1:01
or as close as possible.
Is this reasonably possible? ^_^
Well, you could do something like:
long millisWithinSecond = System.currentTimeMillis() % 1000;
Thread.sleep(1000 - millisWithinSecond);
It won't be exact, mind you - you may need to iterate, which is a bit messy.
However, it would be better not to have to sleep at all. Could you inject a "sleeping service" which would allow you to fake the sleeps out in tests? (I've rarely needed to do that, but I've often injected a fake clock to report different times.) What's the purpose of sleeping in the production code at all?
When you say "the second", do you mean the second of the system clock? You can get the current time in milliseconds via System.currentTimeMillis(), then subtract that from 1000 and sleep by that amount, but keep in mind that Thread.sleep() is not perfectly accurate, so don't be surprised if you overshoot by a bit.

Categories

Resources