android&java源码解析首页投稿(暂停使用,暂停投稿)Android开发

Android CountDownTimer源码解析

2016-04-02  本文已影响2135人  梵依然

title: Android CountDownTimer源码解析
date: 2016-04-02
tags: CountDownTimer


CountDownTimer是android sdk中os包下的一个辅助抽象类,这个类通过handler来实现一个倒计时的操作。在倒计时期间会定期调用用户实现的回调函数。
比如一个简单的使用场景:一个30秒倒计时

 new CountDownTimer(30000, 1000) {

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

onTick方法对这个对象来说是同步的,当onTick方法的实现花费的时间和倒计时的间隔来说需要很久的时候,调用onTick也是按照顺序发生的,方法不会在之前的回调完成之前发生。


    private long mStopTimeInFuture;

    /**
     * 是否取消
     */
    private boolean mCancelled = false;

CountDownTime的构造函数,millisInFuture从调用start方法开始直到倒计时结束的毫秒时间,countDownInterval 接收onTick回调的时间间隔

    public CountDownTimer(long millisInFuture, long countDownInterval) {
        mMillisInFuture = millisInFuture;
        mCountdownInterval = countDownInterval;
    }

取消倒计时

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

开始倒计时

    public synchronized final CountDownTimer start() {
        mCancelled = false;
        if (mMillisInFuture <= 0) {
            onFinish();
            return this;
        }
        mStopTimeInFuture = SystemClock.elapsedRealtime() + mMillisInFuture;
        mHandler.sendMessage(mHandler.obtainMessage(MSG));
        return this;
    }

定期执行的回调,使用的时候需要实现这个方法,millisUntilFinished参数表示剩余时间

    public abstract void onTick(long millisUntilFinished);

当倒计时结束的时候的回调

    public abstract void onFinish();

处理倒计时的handler

    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) {
                    // 剩余时间小于一次时间间隔的时候,不再通知,只是延迟一下
                    sendMessageDelayed(obtainMessage(MSG), millisLeft);
                } else {
                    long lastTickStart = SystemClock.elapsedRealtime();
                    onTick(millisLeft);

                    // 处理用户onTick执行的时间
                    long delay = lastTickStart + mCountdownInterval - SystemClock.elapsedRealtime();

                    // 特殊情况:用户的onTick方法花费的时间比interval长,那么直接跳转到下一次interval
                    while (delay < 0) delay += mCountdownInterval;

                    sendMessageDelayed(obtainMessage(MSG), delay);
                }
            }
        }
    };

通过源码可知,CountDownTimer采用的是handler机制,通过sendMessageDelayed延迟发送一条message到主线程的looper中,然后在自身中收到之后判断剩余时间,并发出相关回调,然后再次发出message的方式。之前实现这种倒计时是通过asynctask,在线程中通过Thread.sleep来实现,通过asyntask的cancel来实现取消,通过构造asynctask传入接口的实现来onTick的类似功能。这个CountDownTimer默认是在当前looper当中,可以是在UI线程也可以是在非UI线程中执行,如果在UI线程中执行,那是不是会稍微加重UI线程的负担?

上一篇下一篇

猜你喜欢

热点阅读