SoFunction
Updated on 2025-03-11

Android CountDownTimer case summary

1. Overview

The countdown function is often used in projects, such as limited-time rush purchases, obtaining verification codes on your mobile phone, etc. Google also helped us encapsulate a class: CountDownTimer, which makes our development more convenient;

2. API

CountDownTimer is an abstract class with two abstract methods, and its API is very simple

public abstract void onTick(long millisUntilFinished);//This is a callback for the specified time each time interval, millisUntilFinished: the remaining time, unit millisecondspublic abstract void onFinish();//This is the callback at the end of the countdown

When using it, only need

new CountDownTimer(long millisInFuture, long countDownInterval)
//millisInFuture:Total countdown time
//countDownInterval:Time intervals per time  All units are milliseconds

3. Basic usage method

Let’s look at the countdown of the SMS verification code. Click to get the verification code. The countdown is 60 seconds. It is not clickable.

new CountDownTimer(60 * 1000, 1000) {
    @Override
    public void onFinish() {
        if (tvCode != null) {
            ("Reacquire");
            (("#E94715"));
            (true);
            (true);
        }

        cancel();
    }

    @Override
    public void onTick(long millisUntilFinished) {
        if (tvCode != null) {
            (false);
            (false);
            (millisUntilFinished / 1000 + "s");
            (("#999999"));
        }
    }
}.start();

Click the button and after successfully obtaining the verification code, you can perform the above operation. Finally, you must start, otherwise it will not be executed.

4. Pay attention to use

CountDownTimer is very easy to use, but there are many pitfalls, so you need to be careful to avoid placing pitfalls.

1. Null pointer: If the cancle method is not called when the activity or fragment is closed and destroyed, its onTick method will continue to be executed. At this time, the UI controls are empty, and it is easy to null pointer if you do not pay attention to judgment.

2. The time is not very accurate:

When we look at the source code of CountDownTimer, we can see that when executing the onTick method, the time spent on the program is subtracted from the Google source code when the program is executed here. Here we can see the rigor of the Google code.

final long millisLeft = mStopTimeInFuture - ();

if (millisLeft <= 0) {
    onFinish();
} else if (millisLeft < mCountdownInterval) {
    // no tick, just delay until done
    sendMessageDelayed(obtainMessage(MSG), millisLeft);
}

So the countdown time at the beginning is 59. Here you can add a little time to the construction method to solve it, such as:

new CountDownTimer(60 * 1000+300, 1000)

3. Memory leak problem

First, let’s look at the source code, the core code is as follows

private Handler mHandler = new Handler() {

    @Override
    public void handleMessage(Message msg) {

        synchronized () {
            if (mCancelled) {
                return;
            }

            final long millisLeft = mStopTimeInFuture - ();

            if (millisLeft <= 0) {
                onFinish();
            } else if (millisLeft < mCountdownInterval) {
                // no tick, just delay until done
                sendMessageDelayed(obtainMessage(MSG), millisLeft);
            } else {
                long lastTickStart = ();
                onTick(millisLeft);

                // take into account user's onTick taking time to execute
                long delay = lastTickStart + mCountdownInterval - ();

                // special case: user's onTick took more than interval to
                // complete, skip to next interval
                while (delay < 0) delay += mCountdownInterval;

                sendMessageDelayed(obtainMessage(MSG), delay);
            }
        }
    }
};

You can see that the principle of CountDownTimer still uses Handler, so it is easy to cause memory leakage problems. When the Activity or Fragment is closed and the countdown is not over yet, it will be executed in the background. Many times, when we use the countdown, we will update the UI, and the controls all hold the reference to the activity. If it is not released for a long time, it will cause memory leakage and even cause the null pointer problem mentioned in 1. Therefore, the cancle method is generally called when the activity or fragment is destroyed.

I encapsulated this myself and wrote it into a tool class for reference:

public class TimeUtils {
    private String color;//The text color can be modified here    WeakReference&lt;TextView&gt; tvCodeWr;//Control software reference to prevent memory leaks    private CountDownTimer timer;


    public TimeUtils(TextView tvCode, String color) {
        super();
         = new WeakReference(tvCode);
         = color;
    }
//This is the countdown execution method    public void RunTimer() {
        timer = new CountDownTimer(60 * 1000 - 1, 1000) {
            @Override
            public void onFinish() {
                if (() != null) {
                    ().setText("Reacquire");
                    ().setTextColor((color));
                    ().setClickable(true);
                    ().setEnabled(true);
                }

                cancel();
            }

            @Override
            public void onTick(long millisUntilFinished) {
                if (() != null) {
                    ().setClickable(false);
                    ().setEnabled(false);
                    ().setText(millisUntilFinished / 1000 + "s");
                    ().setTextColor(("#999999"));
                }
            }
        }.start();
    }
//This method can be called when the activity or fragment is destroyed to prevent memory leakage    public void cancle() {
        if (timer != null) {
            ();
            timer = null;
        }
    }
}

This is the end of this article about the summary of Android CountDownTimer case. For more related Android CountDownTimer content, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!