Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android CountDownTimer Class Lagging Main Thread

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.

like image 668
Tyler Thomas Avatar asked Sep 08 '25 15:09

Tyler Thomas


1 Answers

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();
        }
    }
};
like image 133
Tyler Thomas Avatar answered Sep 10 '25 04:09

Tyler Thomas