Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >CountDownTimer_countdowntimer暂停

CountDownTimer_countdowntimer暂停

作者头像
全栈程序员站长
发布于 2022-10-02 04:51:06
发布于 2022-10-02 04:51:06
1.6K0
举报

大家好,又见面了,我是你们的朋友全栈君。

一,概述

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

二,API

代码语言:c#
AI代码解释
复制
CountDownTimer (long millisInFuture, long countDownInterval)
参数1,设置倒计时的总时间(毫秒)
参数2,设置每次减去多少毫秒

三,基本用法

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

代码语言:java
AI代码解释
复制
    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源码:

代码语言:java
AI代码解释
复制
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方法中如果判断到当前的时间未走完,那么会继续调用

代码语言:scss
AI代码解释
复制
sendMessageDelayed(obtainMessage(MSG), delay);

触发

代码语言:scss
AI代码解释
复制
onTick(millisLeft);

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

代码语言:text
AI代码解释
复制
vertifyView.setText((millisUntilFinished / 1000) + "秒后可重发"); 

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

五,总结

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

代码语言:scss
AI代码解释
复制
activity中
if(!activity.isFinishing()){
//doing something...
}
fragment中
if(getActivity()!=null){
//doing something...
}

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

代码语言:java
AI代码解释
复制
    @Override
public void onFinish() {
if(getFragmentManager()!=null){
dismiss();
}
}

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

代码语言:java
AI代码解释
复制
@Override
public void onDestroy() {
if(timer!=null){
timer.cancel();
timer = null;
}
super.onDestroy();
}

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

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/192098.html原文链接:https://javaforall.cn

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022年9月18日 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
干货三:CountDownTimer倒计时工具类
概述 毫无疑问,我们先来看下官方文档中给的介绍 CountDownTimer 官方定义如下: Schedule a countdown until a time in the future, wit
小小工匠
2021/08/16
4910
CountDownTimer
首先我们使用构造函数创建CountDownTimer对象,需要传递两个参数,并实现两个抽象方法
全栈程序员站长
2022/10/02
5500
CountDownTimer使用心得及总结[通俗易懂]
项目中经常用到倒计时的功能,比如说限时抢购,手机获取验证码等等。而google官方也帮我们封装好了一个类:CountDownTimer,使我们的开发更加方便;
全栈程序员站长
2022/10/02
1.3K0
countdown timer plus_Android10使用
最近博主需要实现一个倒计时相关的功能,被推荐了Android的CountDownTimer工具类,在此说一下CountDownTimer的使用以及源码的解读
全栈程序员站长
2022/09/27
6240
(七十六) CountDownTimer
demo:https://github.com/happyjiatai/demo_csdn/tree/master/demo_76_countdowntimer
全栈程序员站长
2022/10/01
4420
(七十六) CountDownTimer
countdown倒计时安卓软件_倒计时显示装置设计
拿CountDownTimer的源代码看一下,并不复杂,基本上是对Handler的封装,使用send/post delay。这套机制仍然首先于Handler的原理,所以在精度上也不能够保证很精确,只能保证不会早于预期执行。详见我另外一篇介绍Handler send/post delay的文章: Handler sendMessageDelayed()/postDelayed()机制详解。
全栈程序员站长
2022/10/05
4650
countdowntimer的用法_offset counta函数
CountDownTimer类比较简单,总共就一个构造和4个方法。内部是通过handler实现
全栈程序员站长
2022/10/02
5480
countdowntimer的用法_offset counta函数
倒计时应用countdown_countdown timer
CountDownTimer 是android 自带的一个倒计时类,使用这个类可以很简单的实现 倒计时功能
全栈程序员站长
2022/10/02
5960
倒计时应用countdown_countdown timer
Android开发笔记(五十)定时器AlarmManager
Java中的定时器机制有现成的方案,就是Timer+TimerTask。其中TimerTask用来描述时刻到达后的事务处理,而Timer用来调度定时任务,如何时启动、间隔多久再次运行等等。 Timer的调度方法是schedule,主要有三个参数。第一个参数表示用来调度的定时任务,第二个参数表示延迟多久首次启动任务,第三个参数表示间隔多久再次启动任务。 public void schedule(TimerTask task, long delay, long period) 定时任务得自己写个继承自TimerTask的新类,并重写run方法填入具体的事务处理代码。调用Timer的schedule方法,定时任务便会按照调度设置按时启动;TimerTask不能直接设置运行的次数上限,一旦启动就会持续定时运行,除非对象销毁或者调用了TimerTask的cancel方法。调用cancel方法停止定时任务后,若想重启该定时任务,只能重新声明TimerTask对象,并且重新调用schedule方法。 Timer+TimerTask的实质是利用开启Thread来触发定时任务,所以TimerTask实际上运行于非UI线程,也就无法直接操作UI。若想在TimerTask中修改UI控件,得通过Handler发送消息来间接实现。
aqi00
2019/01/18
3.1K0
CountDownTimer_bytebuffer slice
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
全栈程序员站长
2022/10/02
2200
倒计时工具类
在APP开发过程中我们通常会有一个获取手机验证码这样的一个操作,其中有一个倒计时 一般来说就是60s,倒计时期间不可点击 ,计时结束之后重新获取验证码。如下图所示
晨曦_LLW
2020/09/25
6610
相关推荐
干货三:CountDownTimer倒计时工具类
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档