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中移除就好了。