倒计时控件 CountDownTimer 用法和原理分析

移动开发 Android
关于倒计时,有很多种写法,今天我们介绍一种Android自带的倒计时控件CountDownTimer。

[[436754]]

本文转载自微信公众号「Android开发编程」,作者Android开发编程。转载本文请联系Android开发编程公众号。

前言

关于倒计时,有很多种写法,今天我们介绍一种Android自带的倒计时控件CountDownTimer

一、CountDownTimer详解

CountDownTimer:定时执行在一段时间后停止的倒计时,在倒计时执行过程中会在固定间隔时间得到通知;

1、初始化和启动倒计时

  1. public CountTimer(long millisInFuture, long countDownInterval) { 
  2.         super(millisInFuture, countDownInterval); 
  3.     } 
  4.     @Override 
  5.     public void initData() { 
  6.         countDownTimer = new CountDownTimer(200000, 1000) { 
  7.             @Override 
  8.             public void onTick(long millisUntilFinished) { 
  9.                    //单位天 
  10.                     long day = millisUntilFinished / (1000 * 24 * 60 * 60);  
  11.                    //单位时 
  12.                     long hour = (millisUntilFinished - day * (1000 * 24 * 60 * 60)) / (1000 * 60 * 60); 
  13.                     //单位分 
  14.                     long minute = (millisUntilFinished - day * (1000 * 24 * 60 * 60) - hour * (1000 * 60 * 60)) / (1000 * 60); 
  15.                     //单位秒 
  16.                     long second = (millisUntilFinished - day * (1000 * 24 * 60 * 60) - hour * (1000 * 60 * 60) - minute * (1000 * 60)) / 1000; 
  17.             } 
  18.             /** 
  19.              *倒计时结束后调用的 
  20.              */ 
  21.             @Override 
  22.             public void onFinish() { 
  23.             } 
  24.         }; 
  25.         countDownTimer.start(); 
  26.     } 
  27. /** 
  28. * 记得关闭,负责内存溢出 
  29.  */ 
  30. @Override 
  31. protected void onDestroy() { 
  32.     super.onDestroy(); 
  33.     if (countDownTimer != null) { 
  34.         countDownTimer.cancel(); 
  35.         countDownTimer = null
  36.     } 

2、参数和方法介绍

初始化参数

  • millisInFuture 从开始调用start()到倒计时完成并onFinish()方法被调用的毫秒数(倒计时时间,单位毫秒);
  • countDownInterval 接收onTick(long)回调的间隔时间;

方法

  • public final void cancel ()取消倒计时(取消后,再次启动会重新开始倒计时);
  • public abstract void onFinish ()倒计时完成时被调用;
  • public abstract void onTick (long millisUntilFinished)固定间隔被调用;
  • 参数 millisUntilFinished 倒计时剩余时间;
  • public synchronized final CountDownTimer start ()启动倒计时;

二、源码注解

  1. import android.os.Handler; 
  2. import android.os.Message; 
  3. import android.os.SystemClock; 
  4. /** 
  5.  * Schedule a countdown until a time in the future, with 
  6.  * regular notifications on intervals along the way. 
  7.  *官方文档中的使用例子: 
  8.  * Example of showing a 30 second countdown in a text field: 
  9.  * 
  10.  * <pre class="prettyprint"
  11.  * new CountDownTimer(30000, 1000) { 
  12.  * 
  13.  *     public void onTick(long millisUntilFinished) { 
  14.  *         mTextField.setText("seconds remaining: " + millisUntilFinished / 1000); 
  15.  *     } 
  16.  * 
  17.  *     public void onFinish() { 
  18.  *         mTextField.setText("done!"); 
  19.  *     } 
  20.  *  }.start(); 
  21.  * </pre> 
  22.  * 
  23.  * The calls to {@link #onTick(long)} are synchronized to this object so that 
  24.  * one call to {@link #onTick(long)} won't ever occur before the previous 
  25.  * callback is complete.  This is only relevant when the implementation of 
  26.  * {@link #onTick(long)} takes an amount of time to execute that is significant 
  27.  * compared to the countdown interval. 
  28.  */ 
  29. /** 
  30.  * customize from CountDownTimer 
  31.  * Created by zhubingning on 16/09/16. 
  32.  */ 
  33. public abstract class CustomCountDownTimer { 
  34.     /** 
  35.      * Millis since epoch when alarm should stop. 
  36.      */ 
  37.     private final long mMillisInFuture; 
  38.     //!add,为了暂停时保存当前还剩下的毫秒数 
  39.     private long mCurrentMillisLeft; 
  40.     /** 
  41.      * The interval in millis that the user receives callbacks 
  42.      */ 
  43.     private final long mCountdownInterval; 
  44.     private long mStopTimeInFuture; 
  45.     /** 
  46.      * boolean representing if the timer was cancelled 
  47.      */ 
  48.     private boolean mCancelled = false
  49.     /** 
  50.      * @param millisInFuture The number of millis in the future from the call 
  51.      *   to {@link #start()} until the countdown is done and {@link #onFinish()} 
  52.      *   is called. 
  53.      * @param countDownInterval The interval along the way to receive 
  54.      *   {@link #onTick(long)} callbacks. 
  55.      */ 
  56.     //构造函数,(总倒计时毫秒为单位,倒计时间隔) 
  57.     public CustomCountDownTimer(long millisInFuture, long countDownInterval) { 
  58.         mMillisInFuture = millisInFuture; 
  59.         mCountdownInterval = countDownInterval; 
  60.     } 
  61.     //!add, 获取此时倒计时的总时间 
  62.     public long getCountTimes(){ 
  63.         return mMillisInFuture; 
  64.     } 
  65.     /** 
  66.      * Cancel the countdown. 
  67.      */ 
  68.     //取消倒计时,handler从消息队列里取出message 
  69.     public synchronized final void cancel() { 
  70.         mCancelled = true
  71.         mHandler.removeMessages(MSG); 
  72.     } 
  73.     /** 
  74.      * Pause the countdown. 
  75.      */ 
  76.     //!add, 暂停,调用cancel()函数, mCurrentMillisLeft为全局变量自动保存 
  77.     public synchronized final void pause() { 
  78.        cancel(); 
  79.     } 
  80.     /** 
  81.      * Resume the countdown. 
  82.      */ 
  83.     //!add, 恢复函数,根据mCurrentMillisLeft的值重新添加message开始倒计时 
  84.     public synchronized final void resume() { 
  85.         mCancelled=false
  86.         if (mCurrentMillisLeft <= 0) { 
  87.             onFinish(); 
  88.             return ; 
  89.         } 
  90.         mStopTimeInFuture = SystemClock.elapsedRealtime() + mCurrentMillisLeft; 
  91.         mHandler.sendMessage(mHandler.obtainMessage(MSG)); 
  92.         return ; 
  93.     } 
  94.     /** 
  95.      * Start the countdown. 
  96.      */ 
  97.     //开始倒计时,handler发送消息到队列 
  98.     public synchronized final CustomCountDownTimer start() { 
  99.         mCancelled = false
  100.         if (mMillisInFuture <= 0) { 
  101.             onFinish(); 
  102.             return this; 
  103.         } 
  104.         mStopTimeInFuture = SystemClock.elapsedRealtime() + mMillisInFuture; 
  105.         mHandler.sendMessage(mHandler.obtainMessage(MSG)); 
  106.         return this; 
  107.     } 
  108.     /** 
  109.      * Callback fired on regular interval. 
  110.      * @param millisUntilFinished The amount of time until finished. 
  111.      */ 
  112.     //虚拟函数 
  113.     public abstract void onTick(long millisUntilFinished); 
  114.     /** 
  115.      * Callback fired when the time is up. 
  116.      */ 
  117.     //虚拟函数 
  118.     public abstract void onFinish(); 
  119.     private static final int MSG = 1; 
  120.     // handles counting down 
  121.     //handler 
  122.     private Handler mHandler = new Handler() { 
  123.         @Override 
  124.         public void handleMessage(Message msg) { 
  125.             //同步线程 
  126.             synchronized (CustomCountDownTimer.this) { 
  127.                 //判断倒计时是否已取消 
  128.                 if (mCancelled) { 
  129.                     return
  130.                 } 
  131.                 //计算当前剩余毫秒数 
  132.                 final long millisLeft = mStopTimeInFuture - SystemClock.elapsedRealtime(); 
  133.                 //根据剩余毫秒数,或者结束倒计时,或者只延时,或者调用onTick并延时 
  134.                 if (millisLeft <= 0) { 
  135.                     onFinish(); 
  136.                 } else if (millisLeft < mCountdownInterval) { 
  137.                     // no tick, just delay until done 
  138.                     onTick(0);//!add 
  139.                     sendMessageDelayed(obtainMessage(MSG), millisLeft); 
  140.                 } else { 
  141.                     long lastTickStart = SystemClock.elapsedRealtime(); 
  142.                     mCurrentMillisLeft=millisLeft;//!add 
  143.                     onTick(millisLeft); 
  144.                     // take into account user's onTick taking time to execute 
  145.                     long delay = lastTickStart + mCountdownInterval - SystemClock.elapsedRealtime(); 
  146.                     // special caseuser's onTick took more than interval to 
  147.                     // complete, skip to next interval 
  148.                     while (delay < 0) delay += mCountdownInterval; 
  149.                     sendMessageDelayed(obtainMessage(MSG), delay); 
  150.                 } 
  151.             } 
  152.         } 
  153.     }; 

总结

年底了,大家都很忙,大家都多多挣钱,找个好工作,有什么问题就发信息给我。

 

责任编辑:武晓燕 来源: Android开发编程
相关推荐

2022-10-21 15:42:21

倒计时鸿蒙

2011-04-11 09:17:28

Ubuntu倒计时

2017-07-20 16:21:52

UICountDownTidelay

2015-03-23 17:58:04

验证码倒计时并行

2014-03-21 13:46:45

2014-08-18 14:30:27

Android倒计时

2014-02-18 10:36:33

2011-04-11 09:50:56

Ubuntu 11.0

2015-01-21 16:07:57

Android源码验证码倒计时

2011-03-06 15:49:25

webOSBlackBerry

2020-10-28 17:54:49

成都信息安全

2013-04-09 10:01:18

微软Windows XP

2013-10-10 09:23:15

Android 4.4Kitkat

2019-12-13 19:37:00

BashLinux命令

2022-06-14 08:45:27

浏览器IEWindows

2013-10-08 09:24:39

Windows 8.1Windows 8

2013-06-06 11:27:52

iRadioWWDC2013

2019-11-22 11:54:04

数字时代数字中国数字产业

2017-02-09 16:35:17

戴尔
点赞
收藏

51CTO技术栈公众号