倒计时的功能,比如说:发送短信验证码倒计时。

 public class CountDownTimerActivity extends Activity {

     private Button mSend;
private SendCountMessage mCountMessage; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setContentView(R.layout.activity_countdown); mCountMessage = new SendCountMessage();
mSend = (Button) findViewById(R.id.sendCode);
mSend.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mSend.setClickable(false);
//开始执行倒计时的功能
mCountMessage.start();
}
});
} /**
* 我们继承这个抽象类,然后设置好总共的倒计时的时间,以及间隔的时间
* 并且重写 onTick和onFinish方法
*/
class SendCountMessage extends CountDownTimer { /**
* 这里我们还需要设置两个参数:
* 第一个参数:表示我们倒计时的总时间
* 第二个参数:表示我们倒计时的间隔,比如说我们是按一秒数还是二秒
*/
public SendCountMessage() {
super(, );
} /**
* 该方法表示会在构造方法中设定的间隔时间下调用这个方法的。
* 比如说我们设置了间隔时间为1秒的话,那么CountDownTimer
* 将会每个一秒的时间调用 onTick方法一下
* @param millisUntilFinished 表示距离倒计时结束的时间
*/
public void onTick(long millisUntilFinished) {
mSend.setText(millisUntilFinished/ + " 秒后重发");
} /**
* 这里表示倒计时完成结束了
*/
public void onFinish() {
mSend.setClickable(true);
}
} @Override
protected void onDestroy() {
super.onDestroy();
/**
* 最后在这里的时候,我们需要将CountDownTimer取消掉,因为如果我们在销毁界面的时候
* 还没有取消该倒计时器的话,它还会一直在后台不断的跑的直到结束倒计最后才会结束的,
* 这样子为了以免出现问题,我们这里需要取消掉,并且让系统gc该变量。
*/
if(mCountMessage != null) {
mCountMessage.cancel();
mCountMessage = null;
}
}
}

界面布局:

 <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"> ........ <LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="20dip"
android:layout_marginLeft="10dip"
android:layout_marginRight="10dip"
android:layout_marginTop="20dip"> <EditText
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight=""
android:inputType="number"
android:hint="请输入验证码" /> <Button
android:id="@+id/sendCode"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="发送验证码"
android:textSize="18sp" /> </LinearLayout> </LinearLayout>

当我们不需要使用倒计时功能的时候,一定要要调用cancel()方法取消掉,不然它还会在我们页面销毁的时候继续执行的,很有可能会导致内存泄漏的问题

代码分析

 public CountDownTimer(long millisInFuture, long countDownInterval) {
mMillisInFuture = millisInFuture;
mCountdownInterval = countDownInterval;
} public synchronized final CountDownTimer start() {
mCancelled = false;
if (mMillisInFuture <= ) {
onFinish();
return this;
}
//通过当前开始的时间 + 倒计时的总时间来计算出结束的毫秒值
mStopTimeInFuture = SystemClock.elapsedRealtime() + mMillisInFuture;
//然后发送一个message消息给mHandler
mHandler.sendMessage(mHandler.obtainMessage(MSG));
return this;
}

mHandler里面的代码:

 // 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(); //条件一: 如果小于等于0了,说明结束了。
if (millisLeft <= ) {
onFinish();
} else if (millisLeft < mCountdownInterval) {
// no tick, just delay until done
//条件二: 如果距离结束的时间小于我们设定的间隔时间值的时候
// 这个时候就发送一个millisLeft延时的消息
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 < ) delay += mCountdownInterval; //发送一个延时的,时间间隔为我们设定的mCountdownInterval的消息出去
sendMessageDelayed(obtainMessage(MSG), delay);
}
}
}
};

在创建构造函数之前会创建一个内部的Handler对象,主要是用于定时发送消息用的。当我们调用start()方法的时候会发送一个Handler消息出来,这个时候会在mHandler中进行处理。

当Handler收到消息之后就会去跟设定的时间间隔值进行一个比对,然后就发送一个延时的消息。

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

CountDownTimer 源码分析的更多相关文章

  1. Android 关于 CountDownTimer onTick() 倒计时不准确问题源码分析

    一.问题 CountDownTimer 使用比较简单,设置 5 秒的倒计时,间隔为 1 秒. final String TAG = "CountDownTimer"; * , ) ...

  2. ABP源码分析一:整体项目结构及目录

    ABP是一套非常优秀的web应用程序架构,适合用来搭建集中式架构的web应用程序. 整个Abp的Infrastructure是以Abp这个package为核心模块(core)+15个模块(module ...

  3. HashMap与TreeMap源码分析

    1. 引言     在红黑树--算法导论(15)中学习了红黑树的原理.本来打算自己来试着实现一下,然而在看了JDK(1.8.0)TreeMap的源码后恍然发现原来它就是利用红黑树实现的(很惭愧学了Ja ...

  4. nginx源码分析之网络初始化

    nginx作为一个高性能的HTTP服务器,网络的处理是其核心,了解网络的初始化有助于加深对nginx网络处理的了解,本文主要通过nginx的源代码来分析其网络初始化. 从配置文件中读取初始化信息 与网 ...

  5. zookeeper源码分析之五服务端(集群leader)处理请求流程

    leader的实现类为LeaderZooKeeperServer,它间接继承自标准ZookeeperServer.它规定了请求到达leader时需要经历的路径: PrepRequestProcesso ...

  6. zookeeper源码分析之四服务端(单机)处理请求流程

    上文: zookeeper源码分析之一服务端启动过程 中,我们介绍了zookeeper服务器的启动过程,其中单机是ZookeeperServer启动,集群使用QuorumPeer启动,那么这次我们分析 ...

  7. zookeeper源码分析之三客户端发送请求流程

    znode 可以被监控,包括这个目录节点中存储的数据的修改,子节点目录的变化等,一旦变化可以通知设置监控的客户端,这个功能是zookeeper对于应用最重要的特性,通过这个特性可以实现的功能包括配置的 ...

  8. java使用websocket,并且获取HttpSession,源码分析

    转载请在页首注明作者与出处 http://www.cnblogs.com/zhuxiaojie/p/6238826.html 一:本文使用范围 此文不仅仅局限于spring boot,普通的sprin ...

  9. ABP源码分析二:ABP中配置的注册和初始化

    一般来说,ASP.NET Web应用程序的第一个执行的方法是Global.asax下定义的Start方法.执行这个方法前HttpApplication 实例必须存在,也就是说其构造函数的执行必然是完成 ...

随机推荐

  1. ubuntu图形化配置

    安装图形界面 apt-get install ubuntu-desktop 配置用户目录 udo useradd -s /bin/bash -d /home/wykeinstein -m wykein ...

  2. c++的动态绑定和静态绑定

    为了支持c++的多态性,才用了动态绑定和静态绑定. 1.对象的静态类型:对象在声明时采用的类型.是在编译期确定的. 2.对象的动态类型:目前所指对象的声明.在运行期决定.对象的动态类型可以更改,但是静 ...

  3. redis集群报Jedis does not support password protected Redis Cluster configurations异常解决办法

    解决spring-data-redis操作redis集群报“Jedis does not support password protected Redis Cluster configurations ...

  4. 23-hadoop-hive的DDL和DML操作

    跟mysql类似, hive也有 DDL, 和 DML操作 数据类型: https://cwiki.apache.org/confluence/display/Hive/LanguageManual+ ...

  5. MVC源码分析 - Action/Result 过滤器(续)

    上一篇 看到了Action/Result过滤器的执行顺序: OnActionExecuting -> Action -> OnActionExecuted -> OnResultEx ...

  6. 面试题---实现strcpy函数

    #include <stdio.h> char *strcpy(char *strDest,char *strSrc) { if(strDest == NULL || strSrc == ...

  7. ASP.NET MVC HtmlHelper 类的扩展方法

    再ASP.NET MVC编程中用到了R语法,在View页面编辑HTML标签的时候,ASP.NET MVC 为我们准备好了可以辅助我们写这些标签的办法,它们就是HtmlHelper.微软官方地址是:ht ...

  8. Javascript权威指南阅读笔记--第3章类型、值和变量(1)

    之前一直有个想法,好好读完JS权威指南,便于自己对于JS有个较为全面的了解.毕竟本人非计算机专业出生,虽然做着相关行业的工作,但总觉得对于基础的掌握并没有相关专业学者扎实,正好因为辞职待业等原因,还是 ...

  9. Redhat6.8下安装Oracle11gR2

    Step1.配置本地yum源,方便安装依赖包 df -h 补充: df命令查看 linux系统磁盘空间以及使用情况,-h代表方便阅读方式显示  :/dev/sr0为光驱设备名 mkdir cdrom ...

  10. 微信开发(一)基于Wx-java的微信分享功能

    最近在做微信服务号开发,简单总结一下,便于自己学习积累和分享给大家: 环境介绍: Spring+ Spring MVC +Mybatis 开发语言: JAVA 微信公众平台的开发中,微信只公布了一个基 ...