CountDownTimer in Android

来源:互联网 发布:阿里云 宕机 编辑:程序博客网 时间:2024/05/18 01:01

CountDownTimer in Android



最近该一个定时开关机的问题看到里面倒计时使用的是CountDownTimer。
查看一下源码,代码很短,但比较经典,abstract class 、Handler和synchronized都用到了,可以作为一个Example来加深对abstract class 、Handler和synchronized的理解。
 
abstract class:
        CountDownTimer是一个abstract class。
        里面有俩个abstract method让使用者自己实现,public abstract void onTick(long millisUntilFinished);和public abstract void onFinish(); 。
        看过abstrat class可以知道,abstract class有自己实现方法的话必须是final。CountDownTimer的两个实现方法分别是public final void cancel() 和 public synchronized final CountDownTimer start().
Handler:
        CountDownTimer是通过Handler来实现倒计时功能。
        public CountDownTimer(long millisInFutrue,long countDownInterval){}
        start()中通过 mHandler.sendMessage(mHandler.obtainMessage(MSG));  来开始倒计时。若millisInFutrue<=0,会直接调用onFinish()方法一下然后return。
        cancle()中通过 mHandler.removeMessages(MSG); 将handler对应的message queue里的消息清空,从而取消倒计时。
        Handler实现倒计时如下,仔细看一下很容易明白:
 
    // handles counting down    private Handler mHandler = new Handler() {        @Override        public void handleMessage(Message msg) {            synchronized (CountDownTimer.this) {                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                    long delay = lastTickStart + mCountdownInterval - SystemClock.elapsedRealtime();                    // special case: user's onTick took more than interval to                    // complete, skip to next interval                    while (delay < 0) delay += mCountdownInterval;                    sendMessageDelayed(obtainMessage(MSG), delay);                }            }        }    };

synchronized:
        里面start()方法是用synchronized修饰,保证start()方法的同步。
        很简单的验证一下:
                 CountDownTimer cdt =new CountDownTimer(30000, 1000) {                                                   int i=0;                            @Override                            public void onFinish() {                                     // TODO Auto-generated method stub                            }                            @Override                            public void onTick(long millisUntilFinished) {                                     // TODO Auto-generated method stub                                     System.out.println("====>Timer i:"+i++);                            }                   };                   cdt.start();                   cdt.start();
        这样打印出来是123456这样,不会有重复的。
原创粉丝点击