Android中CountDownTimer类详解
一、概述
项目中经常用到倒计时的功能,比如说限时抢购,手机获取验证码等等。而google官方也帮我们封装好了一个类:CountDownTimer,使我们的开发更加方便;
二、API
CountDownTimer是一个抽象类,有两个抽象方法,它的API很简单
public abstract void onTick(long millisUntilFinished);//这个是每次间隔指定时间的回调,millisUntilFinished:剩余的时间,单位毫秒 public abstract void onFinish();//这个是倒计时结束的回调
使用的时候只需要
new CountDownTimer(long millisInFuture, long countDownInterval) //millisInFuture:倒计时的总时长 //countDownInterval:每次的间隔时间 单位都是毫秒
三、基本使用方法
我们以短信验证码的倒计时来看,点击获取验证码,倒计时60s不可点击
new CountDownTimer(60 * 1000, 1000) { @Override public void onFinish() { if (tvCode != null) { tvCode.setText("重新获取"); tvCodeWr.setTextColor(Color.parseColor("#E94715")); tvCode.setClickable(true); tvCode.setEnabled(true); } cancel(); } @Override public void onTick(long millisUntilFinished) { if (tvCode != null) { tvCode.setClickable(false); tvCode.setEnabled(false); tvCode.setText(millisUntilFinished / 1000 + "s"); tvCode.setTextColor(Color.parseColor("#999999")); } } }.start();
点击按钮,获取验证码成功之后就可以执行以上操作,最后一定要start,不然不会执行
四、使用注意
CountDownTimer使用很简单,但是坑很多,需要注意避免踩坑。
1、空指针:
如果在activity或者fragment关闭销毁的时候没有调用cancle方法,它的onTick方法还是会继续执行,这个时候UI控件都为空,不注意判断的话很容易空指针
2、时间不是太准的问题:
我们看CountDownTimer的源码可以看到,在执行onTick的方法时,google源码里面减去了程序执行到这里的时候所消耗的时间,这里可以看出google代码的严谨
final long millisLeft = mStopTimeInFuture - SystemClock.elapsedRealtime(); if (millisLeft <= 0) { onFinish(); } else if (millisLeft < mCountdownInterval) { // no tick, just delay until done sendMessageDelayed(obtainMessage(MSG), millisLeft); }
所以一开始倒计时的时间是59,这里可以在构造方法里面稍微加一点时间就可以解决如:
new CountDownTimer(60 * 1000+300, 1000)
3、内存泄漏问题
首先我们来看源码,核心代码如下
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) { // 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); } } } };
可以看到CountDownTimer的原理还是用到了Handler,所以很容易造成内存泄漏问题,当Activity或者Fragment关闭而倒计时还未结束的时候,会在后台一直执行,而很多时候我们用倒计时会有更新UI的操作,而控件都持有activity的引用,长期得不到释放的话就会造成内存泄漏,甚至会造成1所说的空指针问题,所以一般要在activity或fragment销毁的时候调用cancle方法。
我自己把这个进行了封装,写成了一个工具类以供参考:
public class TimeUtils { private String color;//这里可以修改文字颜色 WeakReference<TextView> tvCodeWr;//控件软引用,防止内存泄漏 private CountDownTimer timer; public TimeUtils(TextView tvCode, String color) { super(); this.tvCodeWr = new WeakReference(tvCode); this.color = color; } //这是倒计时执行方法 public void RunTimer() { timer = new CountDownTimer(60 * 1000 - 1, 1000) { @Override public void onFinish() { if (tvCodeWr.get() != null) { tvCodeWr.get().setText("重新获取"); tvCodeWr.get().setTextColor(Color.parseColor(color)); tvCodeWr.get().setClickable(true); tvCodeWr.get().setEnabled(true); } cancel(); } @Override public void onTick(long millisUntilFinished) { if (tvCodeWr.get() != null) { tvCodeWr.get().setClickable(false); tvCodeWr.get().setEnabled(false); tvCodeWr.get().setText(millisUntilFinished / 1000 + "s"); tvCodeWr.get().setTextColor(Color.parseColor("#999999")); } } }.start(); } //这个方法可以在activity或者fragment销毁的时候调用,防止内存泄漏 public void cancle() { if (timer != null) { timer.cancel(); timer = null; } } }
到此这篇关于Android中CountDownTimer类详解的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持脚本之家。
相关文章
Android ListView的OnItemClickListener详解
这篇文章主要介绍了Android ListView的OnItemClickListener详解的相关资料,涉及到OnItemClickListener的position和id参数做详细的解释的知识点,非常不错,具有参考借鉴价值,需要的朋友参考下2016-07-07详谈Android中Matrix的set、pre、post的区别
下面小编就为大家带来一篇详谈Android中Matrix的set、pre、post的区别。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧2017-04-04Android编程实现QQ表情的发送和接收完整实例(附源码)
这篇文章主要介绍了Android编程实现QQ表情的发送和接收的方法,涉及Android图片资源、正则表达式及对话框的相关操作技巧,具有一定参考借鉴价值,需要的朋友可以参考下2015-11-11Android开发中RecyclerView组件使用的一些进阶技讲解
RecyclerView是Android 5.0以来新加入的一个组件,基本上全面优于ListView,这里我们将来关注Android开发中RecyclerView组件使用的一些进阶技讲解:2016-06-06
最新评论