CountDownTimer 是 android sdk中os包下的一个 抽象类 这个类是通过handler来实现一个倒计时的操作。在倒计时期间会定期调用用户实现的回调函数。拿来用作倒计时非常方便。
1、首先看一下如何使用
public class MyCountDownTimer extends CountDownTimer {
public MyCountDownTimer(long millisInFuture, long countDownInterval) {
super(millisInFuture, countDownInterval);
}
@Override
public void onTick(long millisUntilFinished) {
}
@Override
public void onFinish() {
setAlpha(toAlpha);
}
}
来一个5s倒计时
倒计时总时间5000ms,500ms回调一次方法。
countDownTimer = new MyCountDownTimer(5000, 500);
countDownTimer.start();
2、分析源码
CountDownTime 的构造函数 millisInFuture 是从调用start方法开始直到倒计时结束的毫秒时间,countDownInterval 是接收onTick回调的时间间隔。
/**
* Start the countdown.
*/
public synchronized final CountDownTimer start() {
mCancelled = false;//是否取消
if (mMillisInFuture <= 0) {
onFinish();
return this;
}
mStopTimeInFuture = SystemClock.elapsedRealtime() + mMillisInFuture; //结束倒计时的时间
mHandler.sendMessage(mHandler.obtainMessage(MSG));
return this;
}
开始倒计时
/**
* Start the countdown.
*/
public synchronized final CountDownTimer start() {
mCancelled = false;//是否取消
if (mMillisInFuture <= 0) {
onFinish();
return this;
}
mStopTimeInFuture = SystemClock.elapsedRealtime() + mMillisInFuture; //结束倒计时的时间
mHandler.sendMessage(mHandler.obtainMessage(MSG));
return this;
}
/**
* Cancel the countdown.
*/
public synchronized final void cancel() {
mCancelled = true;
mHandler.removeMessages(MSG);
}
定期会回调的方法
/**
* Callback fired on regular interval.
* @param millisUntilFinished 剩余时间
*/
public abstract void onTick(long millisUntilFinished);
计时结束的回调方法
/**
* Callback fired when the time is up.
*/
public abstract void onFinish();
下面看一下处理及时的 mHandler
// handles counting down
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
synchronized (CountDownTimer.this) {
if (mCancelled) {
return;
}
final long millisLeft = mStopTimeInFuture - SystemClock.elapsedRealtime();
if (millisLeft <= 0) {
onFinish();
} else if (millisLeft < mCountdownInterval) {
// no tick, just delay until done
sendMessageDelayed(obtainMessage(MSG), millisLeft);// 剩余时间小于一次时间间隔的时候,不再通知,只是延迟一下
} else {
long lastTickStart = SystemClock.elapsedRealtime();
onTick(millisLeft);
// take into account user's onTick taking time to execute
//延时时间减去onTick()处理的时间
long delay = lastTickStart + mCountdownInterval - SystemClock.elapsedRealtime();
// special case: user's onTick took more than interval to
// complete, skip to next interval
// 特殊情况:用户的onTick方法花费的时间比mCountdownInterval长,那么直接跳转到下一次mCountdownInterval
while (delay < 0) delay += mCountdownInterval;
sendMessageDelayed(obtainMessage(MSG), delay);
}
}
}
};
CountDownTimer采用的是handler机制,通过sendMessageDelayed延迟发送一条message到主线程的looper中,然后在自身中收到之后判断剩余时间,并发出相关回调,然后再次发出message的方式。取消倒计时,把任务从对MessageQueue中移除就好了。