Reputation: 173
I am trying to use android.os.CountDownTimer to literally show a countdown timer via a textview for fitness purposes. The issue I am having is the timer seems to be having trouble running on the main thread i.e. the countdown will jump 2-4 secs and is clearly being "lagged" - the timer is intended to be in an endless loop until a stop button is pressed.
I am new to Java and Android and cannot figure out how to get the countdown timer running and updating the UI without any conflicts or lagging.
I have attempted to put the CountDown in a Handler/Runnable and an Asynctask with no luck.
MainActivity
CountDownTimer timer;
void countdownTimer() {
long min = countdownMins * 60000;
long sec = countdownSecs * 1000;
long milliseconds = min+sec;
timer = null;
timer = new CountDownTimer(milliseconds, 1000) {
public void onTick(long millisUntilFinished) {
long mins = millisUntilFinished / 60000;
long secs = millisUntilFinished % 60000 / 1000;
String display = String.format("%02d:%02d", mins, secs);
tvTextView.setText(display);
}
public void onFinish() {
countdownTimer();
}
}.start();
}
Many thanks to anyone who can show me how to get this running off the main thread so my UI elements will be smooth.
Upvotes: 4
Views: 8224
Reputation: 173
I decided to take a different approach which has served my purposes very well. No lag or thread issues and can easily be restarted over and over. Hope this helps someone out.
int startCountdown = 5;
int currentCountdown;
Handler countdownHandler = new Handler();
Timer countdownTimer = new Timer();
public void startCountdownTimer() {
currentCountdown = startCountdown;
for (int i = 0; i <= startCountdown; i++) {
TimerTask task = new TimerTask() {
@Override
public void run() {
countdownHandler.post(doA);
}
};
countdownTimer.schedule(task, i * 1000);
}
}
final Runnable doA = new Runnable() {
@Override
public void run() {
if (currentCountdown != 0) {
tvTextView.setText("" + currentCountdown);
currentCountdown--;
} else {
currentCountdown = startCountdown;
startCountdownTimer();
}
}
};
Upvotes: 4
Reputation: 111
If you countdown with changing your TextView fast and frequently. You have to set your TextView width and height in a fix number, or it will lag while calculating your view scale.
Upvotes: 2
Reputation: 4851
Try to use Handler and runnable instead of CountDownTimer. Here is a good article about this approach
http://www.mopri.de/2010/timertask-bad-do-it-the-android-way-use-a-handler/
One more thing you could try is
void countdownTimer() {
final Runnable runnable = new Runnable() {
@Override
public void run() {
tvTextView.setText(display);
}
};
long min = countdownMins * 60000;
long sec = countdownSecs * 1000;
long milliseconds = min + sec;
timer = null;
timer = new CountDownTimer(milliseconds, 1000) {
public void onTick(long millisUntilFinished) {
long mins = millisUntilFinished / 60000;
long secs = millisUntilFinished % 60000 / 1000;
final String display = String.format("%02d:%02d", mins, secs);
textView.post(runnable);
}
public void onFinish() {
countdownTimer();
}
}.start();
}
Upvotes: 3