CountDownTimer浅析

使用 CountDownTimer 实现倒计时任务 在Android开发中,CountDownTimer类提供了一个简单而有效的方法来执行倒计时任务。它允许我们在后台线程中执行任务,并在倒计时结束后在UI线程中更新UI。 阅读详情

一,概述

在项目开发中经常会用到倒计时这个功能,而Android也帮我们封装好了一个类CountDownTimer,给我们的开发带来了很大的方便;

二,API

CountDownTimer (long millisInFuture, long countDownInterval)
参数1,设置倒计时的总时间(毫秒)
参数2,设置每次减去多少毫秒

三,基本用法

以App中获短信取验证码为例:

    private Button btn;
    private TextView vertifyView;  

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        initView();
    }

    private void initView(){
        vertifyView =(TextView) findViewById(R.id.vertifyView);
        btn =(Button) findViewById(R.id.button);
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //1,请求后台...

                //2,触发定时器刷新UI(启动代码最好放在请求后台回调成功之后)
                timer.start();
            }
        });
    }

    private CountDownTimer timer = new CountDownTimer(10000, 1000) {  

        @Override  
        public void onTick(long millisUntilFinished) {  
            vertifyView.setText((millisUntilFinished / 1000) + "秒后可重发");  
        }  

        @Override  
        public void onFinish() {  
            vertifyView.setEnabled(true);  
            vertifyView.setText("获取验证码");  
        }  
    };  

ok~这样一个基本的CountDownTimer案例就完成了

四,存在的问题

CountDownTimer如果使用不当,常常会报空指针异常,甚至造成严重的内存泄漏
5.0源码:

public abstract class CountDownTimer {

    /**
     * Millis since epoch when alarm should stop.
     */
    private final long mMillisInFuture;

    /**
     * The interval in millis that the user receives callbacks
     */
    private final long mCountdownInterval;

    private long mStopTimeInFuture;

    /**
    * 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;
        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;


    // 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();

                if (millisLeft <= 0) {
                    onFinish();
                } else if (millisLeft < mCountdownInterval) {
                    // 剩余时间小于一次时间间隔的时候,不再通知,只是延迟一下
                    sendMessageDelayed(obtainMessage(MSG), millisLeft);
                } else {
                    long lastTickStart = SystemClock.elapsedRealtime();
                    onTick(millisLeft);

                     // 处理用户onTick执行的时间
                    long delay = lastTickStart + mCountdownInterval - SystemClock.elapsedRealtime();

                     // 特殊情况:用户的onTick方法花费的时间比interval长,那么直接跳转到下一次interval
                    while (delay < 0) delay += mCountdownInterval;

                    sendMessageDelayed(obtainMessage(MSG), delay);
                }
            }
        }
    };
}

从源码中我们可以看出,CountDownTimer的内部实现是采用Handler机制,通过sendMessageDelayed延迟发送一条message到主线程的looper中,然后在自身中收到之后判断剩余时间,并发出相关回调,然后再次发出message的方式。

这样的方式其实是有一定弊端的,那就是如果在Activity或者Fragment被回收时并未调用CountDownTimer的cancel()方法结束自己,这个时候CountDownTimer的Handler方法中如果判断到当前的时间未走完,那么会继续调用

sendMessageDelayed(obtainMessage(MSG), delay);

触发

onTick(millisLeft);

当回调了Activity或者fragment中CountDownTimer的onTick方法时,Activity或者Fragment已经被系统回收,从而里面的变量被设置为Null,再调用

vertifyView.setText((millisUntilFinished / 1000) + "秒后可重发");  

vertifyView为空,也就空指针了~
同时,CountDownTimer中的Handler方法还在继续执行,这一块空间始终无法被系统回收也就造成了内存泄漏问题。

五,总结

1,在CountDownTimer的onTick方法中记得判空

activity中
    if(!activity.isFinishing()){
        //doing something...
    }

fragment中
    if(getActivity()!=null){
       //doing something...
    }

2,在配合DialogFragment使用时,如果在onFinish()方法调用了 dismiss()方法让弹框消失,记得 判断getFragmentManager是否为空

    @Override
    public void onFinish() {
        if(getFragmentManager()!=null){
            dismiss();
        }
    }

3,在使用CountDownTimer时,在宿主Activity或fragment生命周期结束的时候,记得调用timer.cancle()方法

@Override
    public void onDestroy() {
        if(timer!=null){
            timer.cancel();
            timer = null;
        }
        super.onDestroy();
    }

遇到问题还是尽量先从控件的源码中寻找答案~相信源码是最好的老师O(∩_∩)O哈哈~

Vue3+codemirror6实现公式(规则)编辑器 vue3+codemirror6+ts实现公式编辑器,可以插入标签、公式,也有补全提示 阅读详情

相关推荐

W25N01GV SPI NAND Flash驱动开发避坑指南:详解2KB缓冲区机制与状态寄存器正确用法

本文深入解析W25N01GV SPI NAND Flash芯片的2KB缓冲区机制与状态寄存器正确用法,提供STM32 HAL和ESP-IDF项目的实战解决方案。涵盖双阶段操作原理、状态寄存器深度解析、时序控制优化及跨平台驱动设计要点,帮助开发者避免常见错误并提升存储性能。

aizhouqian5537的博客 639

安卓CountDownTimer的使用

安卓CountDownTimer的使用

似霰的博客 4507

SAP FI模块实操:用F-28和F-32搞定客户回款与手动清账,别再让未清项报表一团糟

本文详细解析了SAP FI模块中F-28和F-32事务代码在客户回款与手动清账中的实操应用,帮助财务人员高效管理未清项报表。通过标准清账六步法和手动清账实战技巧,解决因操作不规范导致的账务混乱问题,提升应收账款管理效率。

weixin_30292843的博客 451

CountDownTimer使用心得及总结

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

weixin_42564441的博客 4万+

2021-10-29 atcoder ABC157——B - Bingo

B - Bingo 先标记,然后暴力判断,这样最清晰最好想。 #include<iostream> #include<algorithm> #include<cstring> using namespace std; typedef long long LL; int a[110][110],b[110]; int main() { for(int i=1;i<=3;i++) for(int j=1;j<=3;j++) cin>>a[i]

honeistbutter的博客 337

树莓派烧录验证失败:跳过验证步骤实现成功启动的实用技巧

本文针对树莓派烧录系统时常见的验证失败问题,提供了跳过验证步骤实现成功启动的实用技巧。通过分析Windows与Linux文件系统差异导致的SD卡验证报错,指导用户在烧录完成后立即关闭验证窗口,或使用BalenaEtcher等第三方工具规避问题,确保树莓派正常启动。

yyy34的博客 947

CountDownTimer倒计时(Kotlin)

time.setText("倒计时"+hour+"小时"+minute+"分"+second+"秒")var t : Long = 2*60*60*1000 //定义总时长 2小时。time.setText("抢杀结束!CountDownTimer是谷歌官方推荐的计时器,非常简洁。

qq_45877791的博客 1304

SAP MTO模式实战:从库存管理到成本核算的深度解析

本文深入解析SAP MTO(Make-to-Order)模式在制造业中的应用,从库存管理到成本核算的全流程实战技巧。通过对比MTS模式,详细阐述MTO的核心逻辑、库存管理配置、成本核算路径及与PP模块的集成要点,帮助企业实现按单生产的高效管理,优化库存水平和资金占用。

weixin_29204205的博客 709

CountDownTimer使用

CountDownTimer类介绍 CountDownTimer类比较简单,总共就一个构造和4个方法。内部是通过handler实现 CountDownTimer(long time,long interval):参数time是总时间,interval是间隔时间 start():开始倒计时的方法 cancel():取消倒计时的方法 onTink(long time):抽象方法,每个间隔时间

Errol's Blog 2065

Arduino平台软硬件原理及使用——Arduino Uno板卡的使用

Arduino Uno板卡的基本使用

洪博hopes的博客 4172

nvidia系列教程-AGX-Orin linux源码下载编译

NVIDIA AGX Orin 是一款高性能的嵌入式计算平台,广泛应用于人工智能、自动驾驶、机器人等领域。为 AGX Orin 编译定制的 Linux 内核,可以更好地适应特定应用需求,增强系统的灵活性。本文将详细介绍如何下载、配置和编译适用于 AGX Orin 的 Linux 内核源码。本文介绍了如何为 NVIDIA AGX Orin 平台下载、配置和编译定制的 Linux 内核源码。通过编译和部署定制内核,您可以更好地控制系统的行为,并根据特定应用需求进行优化。

flypig has a dream! 1282

Android中使用Handler以及CountDownTimer实现包含倒计时的闪屏页面

上一篇博文《Android中Handler使用浅析》通过实现倒计时闪屏页面的制作引出了Handler的使用方法以及实现原理,博文末尾也提到了实现过程中的Bug,有兴趣的朋友可以点击链接回去看看。今天通过使用Handler以及CountDownTimer来实现完整版的倒计时闪屏(不会出现在退出闪屏页后,依然会跳转页面的现象)。 1. 实现效果如下: 1.1  正常进入跳转的效果以及log显示

潘侯爷的博客 2803

远程声控系统(MATLAB代码见优快云资源)

远程声控系统技术报告 一、题目要求 实现一个远程声音控制系统。首先采集不同的语音指示信号,进行适当压缩;然后通过噪声信道实现远程传输,远端接收后再通过适当计算识别出是何指示,最后送入一个处于未知状态、但能控/能观的控制系统,完成不同的控制动作。 二、问题分解与解决思路 2.1 系统设计 实验中以汉语数字语音1~9作为指令,数字语音“1”代表一号指令,数字语音“2”代表二号指令,依次类推。发送端发出语音“1”,发送端对应的数字语音文件为“1b.wav”,通过信源编码对语音进行压缩编码,然后进行信道编码并进行基

业精于勤,荒于嬉 5733

Android中使用Handler以及CountDownTimer实现包括倒计时的闪屏页面

上一篇博文《Android中Handler使用浅析》通过实现倒计时闪屏页面的制作引出了Handler的用法以及实现原理,博文末尾也提到了实现过程中的Bug,有兴趣的朋友能够点击链接回去看看。今天通过使用Handler以及CountDownTimer来实现完整版的倒计时闪屏(不会出如今退出闪屏页后,依旧会跳转页面的现象)。 1. 实现效果例如以下: (1)正常进入跳转的效果以及...

aodiyi6351的博客 156

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

Android中Handler使用浅析

1. Handler使用引出 现在作为客户,有这样一个需求,当打开Activity界面时,开始倒计时,倒计时结束后跳转新的界面(思维活跃的朋友可能立马想到如果打开后自动倒计时,就类似于各个APP的欢迎闪屏页面),如下图: 作为初学者,可能觉得直接开启一个包含倒序循环的子线程就ok了,具体实现如下: 1.1 Layout界面代码如下: <LinearLayout xmlns

潘侯爷的博客 2322

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

android倒计时闪屏,Android中使用Handler及Countdowntimer实现包含倒计时的闪屏页面

上一篇博文《Android中Handler使用浅析》通过实现倒计时闪屏页面的制作引出了Handler的使用方法以及实现原理,博文末尾也提到了实现过程中的Bug,有兴趣的朋友可以点击链接回去看看。今天通过使用Handler以及CountDownTimer来实现完整版的倒计时闪屏(不会出现在退出闪屏页后,依然会跳转页面的现象)。1. 实现效果如下:1.1 正常进入跳转的效果以及log显示1.2 倒...

weixin_36035466的博客 341

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

android 转圈倒计时,Android中使用Handler及Countdowntimer实现包含倒计时的闪屏页面

上一篇博文《Android中Handler使用浅析》通过实现倒计时闪屏页面的制作引出了Handler的使用方法以及实现原理,博文末尾也提到了实现过程中的Bug,有兴趣的朋友可以点击链接回去看看。今天通过使用Handler以及CountDownTimer来实现完整版的倒计时闪屏(不会出现在退出闪屏页后,依然会跳转页面的现象)。1. 实现效果如下:1.1 正常进入跳转的效果以及log显示1.2 倒...

weixin_31364787的博客 282

android闪屏页倒计时,Android中使用Handler及Countdowntimer实现包含倒计时的闪屏页面...

上一篇博文《Android中Handler使用浅析》通过实现倒计时闪屏页面的制作引出了Handler的使用方法以及实现原理,博文末尾也提到了实现过程中的Bug,有兴趣的朋友可以点击链接回去看看。今天通过使用Handler以及CountDownTimer来实现完整版的倒计时闪屏(不会出现在退出闪屏页后,依然会@R_488_404@面的现象)。1. 实现效果如下:1.1 正常进入跳转的效果以及log...

weixin_28419039的博客 401

Android 后台定时任务的实现和改进

CounDownTimer浅析 CounDownTimer(long millisInFuture, long countDownInterval),但是如果使用不当,常常会报空指针异常? 通过源码分析,CounDownTimer的内部实现是采用Handler机制,通过sendMessageDelayed延迟发送一条message到主线程looper中,然后在自身中收到之后判断剩余时间,并发...

weixin_42009516的博客 1488

Android CountDownTimer(计时器)

简单介绍 介绍: 定时执行在一段时间后停止的倒计时,在倒计时执行过程中会在固定间隔时间得到通知。 参数: millisInFuture 从开始调用start()到倒计时完成并onFinish()方法被调用的毫秒数。(倒计时时间,单位毫秒) countDownInterval 接收onTick(long)回调的间隔时间。(单位毫秒) 公共方法: public final void cance

mazaiting的博客 1663

【Android】CountDownTimer的使用

最后,我们使用CountDownTimer实现了倒计时功能,并在onTick方法中更新了倒计时文本的内容。这样,就实现了根据给定的包名显示应用图标和倒计时的功能。在onTick方法中,可以更新UI上的倒计时时间,而在onFinish方法中,可以执行倒计时结束后的操作。在上述示例中,我们使用了一个单例对象来表示倒计时器,这样我们就可以在任何地方启动倒计时,而不用担心多次创建倒计时器的问题。在onTick方法中,我们更新了UI上的倒计时剩余时间,而在onFinish方法中,我们更新了UI上的提示信息。

aaajj的专栏 2748

Android实现倒计时的几种方案

Android实现倒计时的几种方案

weixin_42602900的博客 2748

Android支持暂停的CountDownTimer倒计时工具类

支持暂停,继续,修复总时长的倒计时, 由CountDownTimer实现的

zmlovelx(帅得不敢出门 程序员群31843264) 2225

CountDownTimer的简单使用

需求:加载某一个界面,在页面中待5秒后再关闭 效果图如下: 设置了一个点击事件,当文字显示为Skip activity时,点击跳转界面。 代码及介绍如下图: 核心功能代码如下 Android自带的CountDownTimer这个工具类,也是通过Handler和子线程来实现的。 //倒计时工具类CountDownTimer //CountDownTimer的构造方法有两个参数...

计蒙不吃鱼的博客 3375
上一篇: Android 带渐变效果的半圆环形进度条
下一篇: Android内存泄漏总结
go_going
博客等级 码龄12年 7粉丝 19原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值