Android CountDownTimer Class Lagging Main Thread

2019-07-17 19:01发布

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.

3条回答
不美不萌又怎样
2楼-- · 2019-07-17 19:29

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.

查看更多
该账号已被封号
3楼-- · 2019-07-17 19:31

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();
        }
    }
};
查看更多
啃猪蹄的小仙女
4楼-- · 2019-07-17 19:40

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();
}
查看更多
登录 后发表回答