It is often encountered in the APP to implement the countdown function. Since the Android framework has built-in countdown functionality, you don’t have to write your own Handler to do it.
Android. OS has an abstract class called CountDownTimer. You can inherit this class and rewrite fun onTick(zipuntilfinished: Long) and fun onFinish().
If you look closely at the CountDownTimer source code, it is implemented using a Handler. The source code is as follows:
// handles counting down
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
synchronized (CountDownTimer.this) {
if (mCancelled) {
return;
}
// Calculate the remaining time
final long millisLeft = mStopTimeInFuture - SystemClock.elapsedRealtime();
// If the remaining implementation is less than or equal to zero, the current handler is terminated
if (millisLeft <= 0) {
onFinish();
} else {
// The time when the usage method is invoked
long lastTickStart = SystemClock.elapsedRealtime();
// Call onTick with the remaining time as an argument
onTick(millisLeft);
// To prevent delays in executing the user's code, record the time it takes to execute the user's methods
// take into account user's onTick taking time to execute
long lastTickDuration = SystemClock.elapsedRealtime() - lastTickStart;
long delay;
// If the remaining time is less than the countdown interval
if (millisLeft < mCountdownInterval) {
// just delay until done
// Calculate delay
delay = millisLeft - lastTickDuration;
// special case: user's onTick took more than interval to
// complete, trigger onFinish without delay
if (delay < 0) delay = 0;
} else {
delay = mCountdownInterval - lastTickDuration;
// special case: user's onTick took more than interval to
// complete, skip to next interval
while (delay < 0) delay += mCountdownInterval; } sendMessageDelayed(obtainMessage(MSG), delay); }}}};Copy the code
CountDownTimer(zipinfuture, countDownInterval): a constructor of CountDownTimer. The first argument takes the time you want to time, and the second argument takes the interval, such as 1S. Note: All parameters here are in milliseconds (1 second =1000 milliseconds)
Fun onTick(zipuntilfinished: Long): is the method called during timing, like updating the UI and so on.
Fun onFinish() : is the method called when timing ends.
If you want to convert milliseconds and minutes into seconds and minutes, you can do it quickly using the TimeUnit class. Want to change MILLISECONDS to seconds, for example, can TimeUnitTimeUnit. MILLISECONDS. ToSeconds (MILLISECONDS) to complete.
So the overall countdown method is as follows:
class CountDown(
millisInFuture: Long,
countDownInterval: Long
) : CountDownTimer(millisInFuture, countDownInterval) {
@SuppressLint("SetTextI18n")
override fun onTick(millisUntilFinished: Long) {
val minutes = TimeUnit.MILLISECONDS.toMinutes(millisUntilFinished)
val seconds = TimeUnit.MILLISECONDS.toSeconds(millisUntilFinished) % 60
// Convert to 2 digits
val minutesStr = String.format("%02d", minutes)
val secondsStr = String.format("%02d", seconds)
// Convert to time format
_leftTime.value = "$minutesStr:$secondsStr"
}
override fun onFinish(a) {
//TODO: Implement the function of the end of the countdown here}}Copy the code
Finally, instantiate the CountDown class and call the start() method to start the CountDown.
val countDown = CountDown(10000.1000)
count.start()
Copy the code
Cancel the countdown by calling count.cancel().