最近博主需要实现一个倒计时相关的功能,被推荐了Android的CountDownTimer工具类,在此说一下CountDownTimer的使用以及源码的解读

以下是一个总计10秒倒计时,每间隔1秒进行回调的例子:

        CountDownTimer timer = new CountDownTimer(10000, 1000) {            @Override            public void onTick(long millisUntilFinished) {                // do something            }            @Override            public void onFinish() {                // do something            }        };        timer.start();
每间隔1秒,CountDownTimer便会调用onTick回调方法执行相应操作
当倒计时结束后,CountDownTimer会调用onFinish回调方法执行相应的操作

看完CountDownTimer的例子后,我们可以看一下CountDownTimer的源码以加深对该工具类的理解,源码如下:

public abstract class CountDownTimer {    /**     * Millis since epoch when alarm should stop.     */    private final long mMillisInFuture;    /**     * The interval in millis that the user receives callbacks     */    private final long mCountdownInterval;    private long mStopTimeInFuture;        /**    * boolean representing if the timer was cancelled    */    private boolean mCancelled = false;    /**     * @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.     */    public CountDownTimer(long millisInFuture, long countDownInterval) {        mMillisInFuture = millisInFuture;        mCountdownInterval = countDownInterval;    }    /**     * Cancel the countdown.     */    public synchronized final void cancel() {        mCancelled = true;        mHandler.removeMessages(MSG);    }    /**     * 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;    }    /**     * 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();    private static final int MSG = 1;    // 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 {                    long lastTickStart = SystemClock.elapsedRealtime();                    onTick(millisLeft);                    // take into account user's onTick taking time to execute                    long lastTickDuration = SystemClock.elapsedRealtime() - lastTickStart;                    long delay;                    if (millisLeft < mCountdownInterval) {                        // just delay until done                        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);                }            }        }    };}

源码并不算长,CountDownTimer作为一个抽象类,其主要方法有如下几个:

  • start:开始进行倒计时
  • cancel:取消倒计时
  • onTick:抽象方法,用于倒计时间隔回调
  • onFinish:抽象方法,用于倒计时结束时回调
看过CountDownTimer的源码后,有几个细节我们需要稍微注意一下:
  1. 在源码第38行中,CountDownTimer会判断是否倒计时已结束,如果是则调用onFinish方法,否则调用onTick方法。因此,在倒计时的最后一秒时,我们并不会收到onTick的回调,取而代之的是onFinish的回调。
  2. 从源码可以看出,CountDownTimer其实与Timer完全没有任何关系,它的倒计时实现是使用Handler机制实现的,因此当我们在非UI线程使用该工具时,需要先初始化Looper
  3. 同上,由于CountDownTimer是基于Handler实现的,其处理以及发送message以及回调onTick处于同一线程,因此当我们在回调方法onTick耗时过多时,可能会影响CountDownTimer预估的回调次数(见源码144行)


更多相关文章

  1. Android系统源码数据库(mmssms.db)(转)
  2. 【Android】EventBus源码解析(3.1.1)
  3. Android 保存文件路径方法
  4. 基于Android客户端的人人网开放平台开发系列教程 (有源码哦)
  5. 阻止一进入页面就弹输入法对话框的方法
  6. Android中SQLiteOpenHelper类的onUpgrade方法的作用
  7. android TabHost(选项卡)的使用方法
  8. Android使用系统方法实现分享到QQ和微信!
  9. Android多种方法获取系统时间

随机推荐

  1. Android学习进阶网址收集
  2. android 设置键盘按钮为发送按钮并监听
  3. getIsDebuggable
  4. Android 检查是否有网络
  5. android 下载文件
  6. Anroid源代码编译相关资源
  7. ANDROID笔记:自定义CheckBox样式
  8. Android NDK开发入门
  9. 初学Android,使用ContentProvider管理多
  10. android 音乐播放器添加音乐分享功能