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类详解的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Android实现倒计时CountDownTimer使用详解

    在开发中会经常用到倒计时这个功能,包括给手机发送验证码等等,之前我的做法都是使用Handler + Timer + TimerTask来实现,现在发现了这个类,果断抛弃之前的做法,相信还是有很多人和我一样一开始不知道Android已经帮我们封装好了一个叫CountDownTimer的类. 从字面上就可以看出来它叫倒数计时器又称定时器或计时器,采用Handler的方式实现,将后台线程的创建和Handler队列封装而成. 看了一下源码,发现这个类的调用还蛮简单,只有四个方法: (1)public a

  • Android 列表倒计时的实现的示例代码(CountDownTimer)

    实习一段时间了,一直想写点技术总结,但一直没找到合适的主题.刚好,最近版本中我负责的模块遇到了个线程相关问题(之前一直画界面,做点基础功能,有点乏味),列表项倒计时的实现. 于是乎,我的第一篇android技术文章就诞生了. [醒目]该demo用Kotlin语言实现. 背景介绍 需要在ListView的item里实现倒计时,初看还挺简单的,但是真正做的时候也遇到了不少坑. 网上有不少类似文章,有用对TextView扩展实现的,也有用自带的CountDownTimer实现的,本文就是用CountD

  • Android使用CountDownTimer类实现倒计时闹钟

    下面使用CountDownTimer类实现倒计时小闹钟,CountDownTimer类其实很简单,一般只需重写其onFinish和onTick方法就可以实现倒计时小闹钟,代码如下: MainActivity: package com.home.brewclock; import android.app.Activity; import android.media.MediaPlayer; import android.os.Bundle; import android.os.CountDownT

  • Android倒计时神器(CountDownTimer)

    Android倒计时神器 - CountDownTimer,供大家参考,具体内容如下 啥是CountDownTimer?​ CountDownTimer是Andorid.os包下一个谷歌为我们封装好的一个倒计时工具.我们吗.平时开发过程中像一些验证码.倒计时的功能,如果自己封装一个倒计时工具就会稍显麻烦.而谷歌这个工具使用起来非常方便. 源码 package android.os; public abstract class CountDownTimer { public CountDownTi

  • Android CountDownTimer案例总结

    目录 一.概述 二.API 三.基本使用方法 四.使用注意 一.概述 项目中经常用到倒计时的功能,比如说限时抢购,手机获取验证码等等.而google官方也帮我们封装好了一个类:CountDownTimer,使我们的开发更加方便: 二.API CountDownTimer是一个抽象类,有两个抽象方法,它的API很简单 public abstract void onTick(long millisUntilFinished);//这个是每次间隔指定时间的回调,millisUntilFinished:

  • Android中CountDownTimer类详解

    一.概述 项目中经常用到倒计时的功能,比如说限时抢购,手机获取验证码等等.而google官方也帮我们封装好了一个类:CountDownTimer,使我们的开发更加方便: 二.API CountDownTimer是一个抽象类,有两个抽象方法,它的API很简单 public abstract void onTick(long millisUntilFinished);//这个是每次间隔指定时间的回调,millisUntilFinished:剩余的时间,单位毫秒 public abstract voi

  • Android中Service服务详解(二)

    本文详细分析了Android中Service服务.分享给大家供大家参考,具体如下: 在前面文章<Android中Service服务详解(一)>中,我们介绍了服务的启动和停止,是调用Context的startService和stopService方法.还有另外一种启动方式和停止方式,即绑定服务和解绑服务,这种方式使服务与启动服务的活动之间的关系更为紧密,可以在活动中告诉服务去做什么事情. 为了说明这种情况,做如下工作: 1.修改Service服务类MyService package com.ex

  • Android中PreferenceActivity使用详解

    目录 一,Preference介绍 二,PreferencesActivity介绍 三,PreferenceActivity的使用 四,PreferenceActivity分别和ListFragment,PreferenceFragment组合使用 五,Preference数据获取 总结 一,Preference介绍 Android提供的preference以键值对的方式来处理这种情况:自动保存设置的数据,并立时生效,而这种使用android sharedpreferences方式进行保存的,不

  • Android中PackageManager使用详解

    目录 前言 引入:AndroidManifest.xml文件节点说明: 相关类的介绍 PackageManger 类 PackageInfo类 PackageItemInfo类 ApplicationInfo类 继承自  PackageItemInfo ActivityInfo类  继承自 PackageItemInfo ServiceInfo 类 总结 前言 Android系统为我们提供了很多服务管理类,包括ActivityManager.PowerManager(电源管理).AudioMan

  • Android中的存储详解

    目录 1.存储在App内部 2.SD卡外部存储 3.SharedPreferences存储 4.使用SQLite数据库存储 4.1 自己完成一个BaseDao类 4.2 使用Google写的API处理 4.3 事务使用 总结 1.存储在App内部 最简单的一种.在尝试过程中发现,手机中很多文件夹都没有权限读写.我们可以将我们需要写的文件存放到App中的files文件夹中,当然我们有权限在整个App中读写文件 可以通过API获取一个file对象,这里的this就是MainActivity类 //

  • Android中menu使用详解

    Menu(菜单)是Android中一定会使用的模块,每个Android项目都会用到Menu来给用户起到选择和导航的作用,提升用户体验,下面通过本文给大家分享android 中menu使用,需要的朋友一起看看吧 很多activity界面中都存在一个菜单栏,就是点击右上角的一个按钮的时候会出现一个下拉列表差不多的东西,这个功能的实现其实只需要下面的两步,每一个activity都可以拥有自己独一无二的menu,具体的格式可以自己进行定义,详细的创建步骤如下 ①在res下的menu中创建file_men

  • Java中Thread类详解及常用的方法

    目录 一.Thread 的常见构造方法 二.Thread 的常见属性 三.创建线程 四.中断线程 五.线程等待 六.获取线程引用 七.线程休眠 八.线程状态 总结 一.Thread 的常见构造方法 方法 说明 Thread() 创建线程对象 Thread(Runnable target) 使用 Runnable 对象创建线程对象 Thread(String name) 创建线程对象并命名 Thread(Runnable target,String name) 使用 Runnable 对象创建线程

  • android中Context深入详解

    以下分别通过Context认知角度,继承关系,对象创建等方面android中Context做了深入的解释,一起学习下. 1.Context认知. Context译为场景,一个应用程序可以认为是一个工作环境,在这个工作环境中可以存在许多场景,coding代码的场景 ,打电话的场景,开会的场景.这些场景可以类比不同的Activity,service. 2.从两个角度认识Context. 第一:Activity继承自Context,同时Activity还实现了其他的interface,我们可以这样看,

  • Android中Intent机制详解及示例总结(总结篇)

    最近在进行android开发过程中,在将 Intent传递给调用的组件并完成组件的调用时遇到点困难,并且之前对Intent的学习也是一知半解,最近特意为此拿出一些时间,对Intent部分进行了系统的学习并进行了部分实践,下面将自己的学习及Intent知识进行了详细的归纳整理,希望能帮助到同样遇到相同问题的博友. 下面是Intent介绍.详解及Intent示例总结: 一.Intent介绍: Intent的中文意思是"意图,意向",在Android中提供了Intent机制来协助应用间的交互

  • Android中 service组件详解

    service组件跟activity组件及其类似,可以说service是没有界面的activity, 当然service的生命周期和activity还是有一定的差别的. service组件一般用在什么地方的,上面讲了service组件没有界面,不用跟用户直接交互, 所以service组件一般运行在后台.比如做一些不需要界面的数据处理等等. 开发service需要两个步骤: 1,定义一个基础service的子类.     2,在AndroidManifest.xml 文件中配置该service.

随机推荐