Handler機(jī)制應(yīng)用之CountDownTimer篇

關(guān)于Handler的內(nèi)部原理及實(shí)現(xiàn)可以查看——Handler機(jī)制源碼之路。

CountDownTimer 是系統(tǒng)提供的一個倒計(jì)時類。其內(nèi)部就是使用了 Handler 封裝的。

1. 用法

先來看一下如何使用。

// 源碼注釋
new CountDownTimer(30000, 1000) {

      public void onTick(long millisUntilFinished) {
         mTextField.setText("seconds remaining: " + millisUntilFinished / 1000);
     }
     
      public void onFinish() {
           mTextField.setText("done!");
     }
}.start();

可以看到,直接 new 一個 CountDownTimer 實(shí)例, 傳入兩個參數(shù), 實(shí)現(xiàn)兩個抽象方法onTick(long)onFinish(), 然后 start()

2. 源碼

接下來通過源碼+注釋說明參數(shù)作用。

2.1 構(gòu)造方法

/**
 * @param millisInFuture The number of millis in the future from the call
 *   to {@link #start()} until the countdown is done and {@link #onFinish()}
 *   is called.
 * @param countDownInterval The interval along the way to receive
 *   {@link #onTick(long)} callbacks.
 *   參數(shù)1 millisInfuture:這個參數(shù)代表你要倒計(jì)時的整體毫秒值,當(dāng)start()開始執(zhí)行時開始倒計(jì)時,當(dāng)?shù)褂?jì)時結(jié)束時回調(diào)onFinish()方法
 *   參數(shù)2 countDownInterval: 代表每次onTick(long)回調(diào)的時機(jī),每countDownInterval差值回調(diào)一次
 */
public CountDownTimer(long millisInFuture, long countDownInterval) {
    mMillisInFuture = millisInFuture;
    mCountdownInterval = countDownInterval;
}

2.2 抽象方法

可以看到 onFinish()onTick(long) 方法為抽象方法,需要子類實(shí)現(xiàn)。

/**
 * Callback fired on regular interval.
 * @param millisUntilFinished The amount of time until finished.
 */
public abstract void onTick(long millisUntilFinished);

/**
 * Callback fired when the time is up.
 */
public abstract void onFinish();

2.3 start() 方法

/**
 * Start the countdown.
 */
public synchronized final CountDownTimer start() {
    mCancelled = false;
    if (mMillisInFuture <= 0) {// 如果開始的時候倒計(jì)時總時長未設(shè)置或?yàn)樨?fù)數(shù),直接結(jié)束。
        onFinish();
        return this;
    }
    mStopTimeInFuture = SystemClock.elapsedRealtime() + mMillisInFuture;// 當(dāng)前時間+總時間,等于要停止的實(shí)際時間
    // 通過Handler 發(fā)送消息,然后在Handler中真正開始計(jì)時
    mHandler.sendMessage(mHandler.obtainMessage(MSG));
    return this;
}

2.4 Handler 部分

// handles counting down
// 內(nèi)部成員變量直接實(shí)例化,說明一個CountDownTimer對應(yīng)一個Handler
private Handler mHandler = new Handler() {

    @Override
    public void handleMessage(Message msg) {

        synchronized (CountDownTimer.this) {// 這個鎖我不知道為什么要加,我的理解在這個方法中一定是回調(diào)的同線程的Handler,Handler也沒有聲明成異步Handler,所以一定是按順序回調(diào)
            if (mCancelled) {
                return;
            }

            final long millisLeft = mStopTimeInFuture - SystemClock.elapsedRealtime();// 要停止的實(shí)際時間-當(dāng)前時間,表示開始倒計(jì)時的總時長

            if (millisLeft <= 0) {
                onFinish();
            } else {
                long lastTickStart = SystemClock.elapsedRealtime();// 上次回調(diào)時間
                onTick(millisLeft);
                long lastTickDuration = SystemClock.elapsedRealtime() - lastTickStart;// 回調(diào)執(zhí)行的時間
                long delay;
                if (millisLeft < mCountdownInterval) {// 需要倒計(jì)時的時間小于單次間隔
                    delay = millisLeft - lastTickDuration;
                    // 如果執(zhí)行時間過長,會導(dǎo)致計(jì)時不準(zhǔn),這時直接進(jìn)入下一次倒計(jì)時
                    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);
            }
        }
    }
};

2.5 cancel() 方法

public synchronized final void cancel() {
    mCancelled = true;
    mHandler.removeMessages(MSG);
}

3. 總結(jié)

很簡單的一個類,就是使用Handler封裝的倒計(jì)時工具。需要注意的就是

  • CountDownTimer 創(chuàng)建的時候,一定要保證所在線程的 Looper 已經(jīng)開啟。
  • Activity 注銷時,記著取消定時器。
  • 定時器中不要留存 Activity 的強(qiáng)引用。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容