深入解读一下`android.os.CountDownTimer`

news2024/11/19 8:43:19

请添加图片描述

简介

在 Android 开发中,CountDownTimer 是一个非常有用的类,它可以用于倒计时任务,比如倒计时器、限时活动等。CountDownTimer 提供了一个简单的方式来实现定时操作,无需我们手动管理线程和计时器。

本文将深入解析 CountDownTimer 的工作原理、使用方法及其在实际应用中的一些技巧。

CountDownTimer 的基本用法

构造函数

要使用 CountDownTimer,我们首先需要创建一个实例。其构造函数如下:

public CountDownTimer(long millisInFuture, long countDownInterval) {
    // Implementation
}
  • millisInFuture: 表示倒计时的总时间(以毫秒为单位)。
  • countDownInterval: 表示倒计时间隔(以毫秒为单位),每隔多长时间回调一次 onTick 方法。

方法

CountDownTimer 提供了两个关键方法:

  1. onTick(long millisUntilFinished): 每隔 countDownInterval时间会回调该方法,参数 millisUntilFinished 表示倒计时剩余的时间。
  2. onFinish(): 倒计时完成时会回调该方法。

示例代码

下面是一个简单的示例,演示如何使用 CountDownTimer

new CountDownTimer(30000,1000) {
    public void onTick ( long millisUntilFinished){
        Log.d("CountDownTimer", "剩余时间: " + millisUntilFinished / 1000);
    }
    public void onFinish () {
        Log.d("CountDownTimer", "倒计时结束");
    }
}.

start();

在这个示例中,我们创建了一个 30 秒的倒计时器,每秒回调一次 onTick方法,并在倒计时结束时回调 onFinish 方法。

Kotlin 示例代码

下面是一个使用 Kotlin 实现的示例:

object : CountDownTimer(30000, 1000) {
    override fun onTick(millisUntilFinished: Long) {
        Log.d("CountDownTimer", "剩余时间: ${millisUntilFinished / 1000}")
    }
    override fun onFinish() {
        Log.d("CountDownTimer", "倒计时结束")
    }
}.start()

深入理解 CountDownTimer

工作原理

CountDownTimer 的实现主要依赖于 HandlerRunnable。在其内部,通过 Handler 来发送延时消息,从而实现定时功能。

CountDownTimer 内部,有一个 Handler对象,负责在指定的时间间隔内不断发送消息。每当消息到达时,倒计时器的剩余时间会减少相应的间隔,并回调 onTick方法。

源码解析

让我们深入看看 CountDownTimer 的源码,了解其内部实现。

public abstract class CountDownTimer {
    private final long    mMillisInFuture;  // 倒计时总时间
    private final long    mCountdownInterval;  // 每次回调的间隔时间
    private       long    mStopTimeInFuture;  // 结束时间点
    private       boolean mCancelled = false;  // 取消标志

    // 构造函数,初始化倒计时总时间和回调间隔
    public CountDownTimer(long millisInFuture, long countDownInterval) {
        mMillisInFuture = millisInFuture;
        mCountdownInterval = countDownInterval;
    }

    // 取消倒计时
    public synchronized final void cancel() {
        mCancelled = true;
        mHandler.removeMessages(MSG);
    }

    // 开始倒计时
    public synchronized final CountDownTimer start() {
        mCancelled = false;
        if (mMillisInFuture <= 0) {
            onFinish();
            return this;
        }
        mStopTimeInFuture = SystemClock.elapsedRealtime() + mMillisInFuture;
        mHandler.sendMessage(mHandler.obtainMessage(MSG));
        return this;
    }

    // 每次间隔回调的抽象方法,需要子类实现
    public abstract void onTick(long millisUntilFinished);

    // 倒计时结束回调的抽象方法,需要子类实现
    public abstract void onFinish();

    private static final int MSG = 1;  // 消息标识

    // Handler 用于处理定时消息
    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) {
                    // 剩余时间小于回调间隔时,最后一次回调
                    mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG), millisLeft);
                } else {
                    long lastTickStart = SystemClock.elapsedRealtime();
                    onTick(millisLeft);  // 每次间隔回调

                    long delay = lastTickStart + mCountdownInterval - SystemClock.elapsedRealtime();
                    while (delay < 0) delay += mCountdownInterval;

                    // 发送下一个消息
                    mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG), delay);
                }
            }
        }
    };
}

在这段代码中,CountDownTimer 使用 Handler在指定的时间间隔内发送消息,并根据剩余时间来决定是调用 onTick 还是 onFinish 方法。

CountDownTimer 的应用场景

倒计时显示

CountDownTimer最常见的应用场景之一是倒计时显示。可以用于活动倒计时、游戏中的计时器等。例如,在一个限时抢购活动中,可以使用 CountDownTimer实时更新剩余时间。

限时任务

另外一个常见的场景是限时任务。比如在一些答题应用中,每道题都有答题时间限制,可以使用 CountDownTimer来实现这种限时效果。

计时提醒

CountDownTimer 还可以用作计时提醒工具。在一些健身应用中,可以使用 CountDownTimer
来计时每个运动的持续时间,并在时间结束时提醒用户。

注意事项

精度问题

由于 CountDownTimer 基于 Handler 实现,其精度可能会受到系统调度的影响。如果需要高精度的定时操作,建议使用更低层的计时机制。

内存泄漏

使用 Handler 时需要注意内存泄漏问题。在使用 CountDownTimer 时,确保在不需要时调用 cancel方法,并在合适的生命周期方法中清理资源。

结论

CountDownTimer是一个非常实用的工具类,简化了倒计时功能的实现。通过理解其工作原理和使用方法,我们可以更好地应用它来满足各种需求。在实际开发中,注意其精度和内存管理问题,可以让我们的应用更加健壮和高效。

希望本文对你理解 CountDownTimer 有所帮助,如果有任何问题或建议,欢迎留言讨论。

感谢阅读,Best regards!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1882187.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

HiBit Uninstaller:软件批量卸载,一触即得

名人说&#xff1a;莫道谗言如浪深&#xff0c;莫言迁客似沙沉。 ——刘禹锡《浪淘沙》 创作者&#xff1a;Code_流苏(CSDN)&#xff08;一个喜欢古诗词和编程的Coder&#x1f60a;&#xff09; 目录 一、软件介绍1、HiBit Uninstaller2、核心功能 二、下载安装1、下载2、安装 …

文件操作与管理

程序经常需要访问文件和目录&#xff0c;读取文件信息或写入文件信息&#xff0c;在Python语言中对文件的读写是通过文件对象&#xff08;file object&#xff09;实现的。Python的文件对象也称为类似文件对象或流&#xff08;stream&#xff09;&#xff0c;因为Python提供一种…

13_网络安全

目录 网络安全协议 网络安全协议 PGP协议 网络安全技术 防火墙技术 入侵检测系统 入侵防御系统 杀毒软件 蜜罐系统 计算机病毒与木马 网络安全协议 网络安全协议 物理层主要使用物理手段隔离、屏蔽物理设备等&#xff0c;其他层都是靠协议来保证传输的安全&#xff…

【python刷题】蛇形方阵

题目描述 给出一个不大于 99 的正整数n&#xff0c;输出n*n的蛇形方阵。从左上角填上1开始&#xff0c;顺时针方向依次填入数字&#xff0c;如同样例所示。注意每个数字有都会占用3个字符&#xff0c;前面使用空格补齐。 输入 输入一个正整数n,含义如题所述 输出 输出符合…

ITK-二值阈值分割

作者&#xff1a;翟天保Steven 版权声明&#xff1a;著作权归作者所有&#xff0c;商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处 什么是二值阈值分割&#xff1f; 二值阈值分割是一种常见的图像处理技术&#xff0c;用于将图像的像素值分成两个类别&#xff1…

基于GTX的64B66B编码的自定义协议发送模块(高速收发器二十一)

点击进入高速收发器系列文章导航界面 1、64B66B组帧原理 前文讲解64B66B编码原理时&#xff0c;已经讲解过组帧的原理&#xff0c;包括数据帧和控制帧两种&#xff0c;区别在于同步码不同。 下图是802.3的以太网控制协议&#xff0c;其中S表示起始位&#xff0c;T表示停止位。为…

LINUX系统编程:多线程互斥

目录 1.铺垫 2.线程锁接口的认识 静态锁分配 动态锁的分配 互斥量的销毁 互斥量加锁和解锁 3.加锁版抢票 4.互斥的底层实现 1.铺垫 先提一个小场景&#xff0c;有1000张票&#xff0c;现在有4个进程&#xff0c;这四个进程疯狂的去抢这1000张票&#xff0c;看看会发生什…

熊猫烧香是什么?

熊猫烧香&#xff08;Worm.WhBoy.cw&#xff09;是一种由李俊制作的电脑病毒&#xff0c;于2006年底至2007年初在互联网上大规模爆发。这个病毒因其感染后的系统可执行文件图标会变成熊猫举着三根香的模样而得名。熊猫烧香病毒具有自动传播、自动感染硬盘的能力&#xff0c;以及…

简单爬虫案例——爬取快手视频

网址&#xff1a;aHR0cHM6Ly93d3cua3VhaXNob3UuY29tL3NlYXJjaC92aWRlbz9zZWFyY2hLZXk9JUU2JThCJTg5JUU5JTlEJUEy 找到视频接口&#xff1a; 视频链接在photourl中 完整代码&#xff1a; import requestsimport re url https://www.kuaishou.com/graphql cookies {did: web_…

C语言 | Leetcode C语言题解之第207题课程表

题目&#xff1a; 题解&#xff1a; bool canFinish(int numCourses, int** prerequisites, int prerequisitesSize, int* prerequisitesColSize) {int** edges (int**)malloc(sizeof(int*) * numCourses);for (int i 0; i < numCourses; i) {edges[i] (int*)malloc(0);…

一点连接千家银行,YonSuite让“银企对账”一键确认

在当今数智化浪潮下&#xff0c;成长型企业面临着前所未有的机遇与挑战。特别是在与银行的对接以及银企对账等方面&#xff0c;传统的手动操作模式已难以满足企业高效、安全的金融管理需求。用友YonSuite作为一款全场景SaaS应用服务&#xff0c;凭借其强大的银企直联功能&#…

【C++ 初阶路】--- C++内存管理

目录 一、C/C内存分布二、C内存管理方式2.1 new/delete操作内置类型2.2 new和delete操作自定义类型 三、operator new与operator delete函数四、new和delete的实现原理4.1 内置类型4.2 自定义类型 一、C/C内存分布 int globalVar 1; static int staticGlobalVar 1; void Tes…

树立行业标杆,林清轩获“以油养肤开创者”市场地位认证

从0到1的创造&#xff0c;才能快速实现从1到100的裂变&#xff0c;这是亘古不变的商业逻辑。 6月25日&#xff0c;知名美妆国货品牌林清轩&#xff0c;获得了CIC灼识的市场地位确认书&#xff0c;确定“以油养肤开创者” 的地位。 近两年&#xff0c;以油养肤的概念逐渐兴起&am…

【Python】入门Python,你必须了解这些事

个人主页&#xff1a;【&#x1f60a;个人主页】 系列专栏&#xff1a;【❤️Python】 文章目录 前言一、认识Python什么是Python&#xff1f;!Python的起源Python的特点简洁易读跨平台&#xff0c;可移植拥有强大的库和框架面向对象 Python的优缺点优点缺点 Python的应用环境扩…

【第六节】C/C++静态查找算法

目录 前言 一、搜索查找 二、查找算法 1. 线性查找&#xff08;Linear Search&#xff09; 2. 二分查找&#xff08;Binary Search&#xff09; 3. 插值查找&#xff08;Interpolation Search&#xff09; 4. 哈希查找&#xff08;Hash Search&#xff09; 5. Fibonacc…

气膜足球馆需要投资多少—轻空间

随着足球运动的普及和人们对健康生活方式的追求&#xff0c;建设高质量的足球场地成为许多城市和社区的需求。在众多建设方案中&#xff0c;气膜足球馆因其独特的优势&#xff0c;逐渐成为一种受欢迎的选择。轻空间将探讨建设气膜足球馆所需的投资情况&#xff0c;并分析其成本…

InnoDB 表空间2---系统表空间

系统表空间 了解完了独立表空间的基本结构&#xff0c;系统表空间的结构也就好理解多了&#xff0c;系统表空间的结构和独立表空间基本类似&#xff0c;只不过由于整个MySQL进程只有一个系统表空间&#xff0c;在系统表空间中会额外记录一些有关整个系统信息的页&#xff0c;所…

MySQL之主从同步、分库分表

1、主从同步的原理 MySQL主从复制的核心是二进制日志 二进制日志&#xff08;binlog&#xff09;记录了所有DDL语句和DML语句&#xff0c;但不包括数据查询&#xff08;select、show&#xff09;语句。 1.1、复制分三步 master主库在事务提交时&#xff0c;会把数据变更记录…

干货分享:Spring中经常使用的工具类(提示开发效率)

环境&#xff1a;Spring5.3…30 1、资源工具类 ResourceUtils将资源位置解析为文件系统中的文件的实用方法。 读取classpath下文件 File file ResourceUtils.getFile(ResourceUtils.CLASSPATH_URL_PREFIX "logback.xml") ; // ...读取文件系统文件 file Resou…

淘系-万相台无界实操运营课:淘系 付费工具课(40节课)

课程目录 01_万相台无界系统性忖费推广思维.mp4 02_万相台无界七大推广场景详解.mp4 03关键词推广计划之标准计划搭建技巧.mp4 04_关键词推广之智能计划推广技巧.mp4 05_关键词推广之趋势选品计划推广技巧.mp4 06关键词推广之智能选品计划推广技巧.mp4 07_非标品的关键词…