Reputation: 1133
I am making an Android App that at some activity shows a timer with hours minutes and seconds. As seconds value will update every second, I was thinking to make a thread with 1000 ms sleep, after each cycle it will add 1 to seconds and update the text view. Accordingly it will calculate minutes and hours and update the respective text views.
But I have one doubt in mind, are threads reliable enough to accomplish such a task or should I use inbuilt library function to get seconds after every cycle ? I am a little concerned about getting my timer getting out of sync if I rely completely on thread to calculate time.
Upvotes: 6
Views: 380
Reputation: 18712
Use Handler. Here's a very good detailed post on that.
long startTime = 0;
Handler timerHandler = new Handler();
Runnable timerRunnable = new Runnable() {
@Override
public void run() {
long millis = System.currentTimeMillis() - startTime;
int seconds = (int) Math.round(diff / ((double)1000));
int minutes = (int) Math.round(seconds / ((double)60));
seconds = seconds % 60;
// Use the seconds
timerHandler.postDelayed(this, 500);
}
};
Start timer-
startTime = System.currentTimeMillis();
timerHandler.postDelayed(timerRunnable, 0);
Stop timer-
timerHandler.removeCallbacks(timerRunnable);
On pause-
timerHandler.removeCallbacks(timerRunnable);
Upvotes: 6
Reputation: 4380
As others have pointed out, sleep(millis)
only guarantees to sleep for at least the amount of milliseconds - which means if you use 1000
instead of an offset it will be lagging behind.
Use with offset:
long last = System.currentTimeMillis();
while (true) {
long current = System.currentTimeMillis();
Thread.sleep(last-current);
last = current;
incrementSeconds();
}
Upvotes: 1
Reputation: 489
Its not possible with simple thread with sleep in android. Just use runnable thread.
Start this when u need to update your textview according to seconds . In this i tried with minutes, seconds and millise3conds .
Just check it out.
Create a textview , nd set text with the below runnable.
private Runnable updateTimerThread = new Runnable() {
public void run() {
timeInMilliseconds = SystemClock.uptimeMillis() - startTime;
updatedTime = timeSwapBuff + timeInMilliseconds;
int secs = (int) (updatedTime / 1000);
int mins = secs / 60;
secs = secs % 60;
int milliseconds = (int) (updatedTime % 1000);
t1.setText("" + mins + ":"
+ String.format("%02d", secs) + ":"
+ String.format("%03d", milliseconds));
customHandler.postDelayed(this, 0);
}
};
Upvotes: 1
Reputation: 9716
Sleep with 1000 ms delay is bad option, since there is always a jitter and also some CPU time is spent on execution of your routine.
I would propose to profit from ScheduledExecutorService.scheduleAtFixedRate method, that will call your implementation at fixed rate.
Upvotes: 3
Reputation: 22158
While if you say sleep for 1 second the thread will sleep for 1 second, the actual time at which your instruction takes place when the thread wakes up depends on other factors such as thread scheduling of the OS and the CPU. Its unlikely it will have a huge impact, but why don't you simply keep track of the actual timestamps so that you know exactly how much time has elapsed, and correct accordingly if there is any difference?
You can use something simple like System.currentTimeMillis()
Upvotes: 1
Reputation: 24630
But I have one doubt in mind, are threads reliable enough to accomplish such a task
No, they aren't.
You can use a thread to update the clock display but you should read System.currentTimeMillis() (or similiar) again.
Upvotes: 1
Reputation: 64915
Sleep is not good enough.
Sleep will pause the thread for a minimum of the specified period of time, but the actual sleep period may be longer than the specified time.
Upvotes: 8
Reputation: 7057
Thread sleep
should never be relied upon. It does not guaranty the exact time difference.
I'd suggest you to use a timer task. It's easy to use and considerably reliable.
Good luck.
Upvotes: 2
Reputation: 46229
With the logic you have described you will indeed get some drifting, i.e. the small error you may get every cycle will add up to a significant amount. It is easily remedied though.
Just keep a variable holding the time of the last trigger. When the sleep is done, add 1000
to the last trigger time, calculate the remainder until that time, and sleep for that long instead. This way you may get the occasional late trigger, but it will quickly be remedied.
Upvotes: 2