简介


CounterDownTImer是Android系统自带的一个倒计时器,特别是在做app登录时会比较有用。

用法

非常简单,比如做个倒计时60s且每隔1s会刷新一下,可以这样写

new CountDownTimer(60000, 1000) {public void onTick(long millisLeft) {mTextField.setText("seconds millisLeft: " + millisLeft / 1000);}public void onFinish() {mTextField.setText("done!");}}.start();

CountDownTimer类的构造器接受2个参数,第一个为倒计时总时间,第二个为间隔时间单位。注意2个参数单位都是ms。当调用start方法后,系统会每间隔一段时间(第二个参数指定)调用onTrick方法,倒计时结束会执行onFinish方法;那么到底是怎么实现的呢?

下面是源码以及对源码理解所做的注释,就不再解释了

package android.os;
/*** The calls to {@link #onTick(long)} are synchronized to this object so that* one call to {@link #onTick(long)} won't ever occur before the previous* callback is complete.  This is only relevant when the implementation of* {@link #onTick(long)} takes an amount of time to execute that is significant* compared to the countdown interval.*/
public abstract class CountDownTimer {/*** Millis since epoch when alarm should stop.*/private final long mMillisInFuture;//倒计时总耗时间(单位:ms)/*** The interval in millis that the user receives callbacks*/private final long mCountdownInterval;//间隔时间(单位:ms)private long mStopTimeInFuture;//倒计时结束时间戳(单位:ms)/*** 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;//判断构造器接受的参数是否合法,//如果倒计时总耗时间<=0 直接调用onFinish方法,并立即返回该对象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;//注意此处mHandler成员变量的构造器没有传入Looper哦// handles counting downprivate Handler mHandler = new Handler() {@Overridepublic void handleMessage(Message msg) {synchronized (CountDownTimer.this) {if (mCancelled) {return;}//计算还剩下多少时间需要倒计时final long millisLeft = mStopTimeInFuture - SystemClock.elapsedRealtime();if (millisLeft <= 0) {onFinish();} else if (millisLeft < mCountdownInterval) {//如果还剩的时间比间隔时间还小,不再调用onTick方法,延迟剩余的时间发送通知后直接执行onFinish方法// no tick, just delay until donesendMessageDelayed(obtainMessage(MSG), millisLeft);} else {long lastTickStart = SystemClock.elapsedRealtime();onTick(millisLeft);/***delay = 间隔时间-onTick消耗的时间*如果delay >=0 ,为保证onTick是严格间隔时间执行,延迟delay发送通知*如果delay < 0, 说明执行onTick方法消耗的时间比间隔时间大,只能跳过当前时序,直接进入下一个时序**/// take into account user's onTick taking time to executelong delay = lastTickStart + mCountdownInterval - SystemClock.elapsedRealtime();// special case: user's onTick took more than interval to// complete, skip to next intervalwhile (delay < 0) delay += mCountdownInterval;sendMessageDelayed(obtainMessage(MSG), delay);}}}};
}

总结:

  1. 如果onTick涉及到UI修改,CountDownloadTimer对象创建确保在UI线程创建
  2. CountDownTimer为了保持在间隔时间内准确通知onTick,会计算onTick时间,如果onTick消耗时间大于指定的间隔时间,只能在下个时间间隔内执行onTick了

Android-源码剖析CountDownTimer(倒计时类)相关推荐

  1. Android源码剖析之Framwork层后记篇(硬件消息传递、apk管理、输入法框架、编译过程)

    本文来自http://blog.csdn.net/liuxian13183/ ,引用必须注明出处! 既然写到后记篇,就代表本系列到此为止,暂时告一段落:其他一些Manager随后有时间再补,就像源码的 ...

  2. ChartCtrl源码剖析之——CChartAxis类

    CChartAxis类用来绘制波形控件的坐标轴,这个源码相对较复杂,当初阅读的时候耗费了不少精力来理解源码中的一些实现细节. CChartAxis类的头文件. #if !defined(AFX_CHA ...

  3. 【Android源码剖析】(API 19)[View-----MeasureSpec]

    MeasureSpec MeasureSpec的全称是Measure Specification,意为"测量规格".一个MeasureSpec对象封装了父布局传递给子布局的布局要求 ...

  4. Android源码剖析之Framwork层消息传递,震撼来袭免费下载!

    简介 首先,Android是不是真的找工作越来越难呢?这个可能是大家最关心的.这个受大的经济环境以及行业发展前景的影响,同时也和个人因素有关. 近期一方面是所在的公司招聘Java开发人员很难招到合适的 ...

  5. boost源码剖析之:泛型函数指针类boost::function(rev#3)

    boost源码剖析之:泛型函数指针类boost::function(rev#3) 刘未鹏 C++的罗浮宫(http://blog.csdn.net/pongba)   Note: 并非新作,03年曾放 ...

  6. boost源码剖析之:泛型指针类any之海纳百川(rev#2)

    boost源码剖析之:泛型指针类any之海纳百川(rev#2) 刘未鹏 C++的罗浮宫(http://blog.csdn.net/pongba) 动机 C++是强类型语言,所有强类型语言对类型的要求都 ...

  7. Android多线程研究(1)——线程基础及源码剖析

    从今天起我们来看一下Android中的多线程的知识,Android入门容易,但是要完成一个完善的产品却不容易,让我们从线程开始一步步深入Android内部. 一.线程基础回顾 package com. ...

  8. Android:从源码剖析Hander机制

    引言 Hander机制是安卓开发中一个重要的消息机制,也是面试的常客.本篇文章是结合书籍和源码,进行一个梳理总结,方便大家更好的理解Hander机制. Hander的两种用法及使用场景 这里介绍两种最 ...

  9. 【Android源码-AMS】(一)Instrumentation类解析

    注:转载请注明来自Nemo,http://blog.csdn.net/nemo__ 一.包名          android.app.Instrumentation 这里研究AMS中的Instrum ...

最新文章

  1. 2021年,神经科学AI有这几大趋势
  2. 看看那些不讲码德的坏习惯
  3. 【Swing编写图形用户界面】操作系统之磁盘调度算法图形界面和性能比较
  4. Markdown 语法介绍
  5. C++中常用字符串相关的编程题
  6. java简单纸牌游戏_活动回顾 | 畅玩法语纸牌游戏
  7. java string字符拼接符+的研究
  8. 软件工程之软件概要设计
  9. C# 图书管理系统源码(三层架构,含数据库)
  10. SQL注入理解与防御
  11. 揭露狂拽炫酷吊炸天,靠抄袭起家的非主流崇才科技
  12. linux中的xorg进程占用内存资源释放
  13. 中国影视IP制作行业投资规划动态及发展趋向分析报告2022-2028年版
  14. 钉钉机器人项目踩过的坑
  15. Redux-Devtools调试工具安装使用
  16. ABP 多租户 对应多数据库 租户启动报错
  17. python期货程序化交易高手心得_位顶级高手谈期货心得
  18. android studio 安装haxm,android studio中的HAXM配置
  19. 超详细!关于万能头文件<bits/stdc++.h>的细节
  20. 幼儿园计算机课件制作评比表,幼儿园多媒体课件的设计、制作与评价.ppt

热门文章

  1. 台式计算机的配置清单(硬件和软件),计算机硬件配置清单大 全!值得收藏哦
  2. maven修改setting文件后重启_Maven项目构建
  3. 【小白学习C++ 教程】九、C++中字符型、字符串和转义字符
  4. 为了OFFER,我加深学习队列,现在还一脸懵逼
  5. 从三角不等式到Margin Softmax
  6. 概率视角下的线性模型:逻辑回归有解析解吗?
  7. 直播 | WWW 2021:基于结构增强文本表示学习的知识图谱补全方法
  8. 语言模型微调领域有哪些最新进展?一文详解最新趋势
  9. 3步理清Python数据分析关键点,新手必看
  10. 安卓scrollview无法滑动_安卓上线前,小光有话想对你们说