首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >countdowntimer的用法_offset counta函数

countdowntimer的用法_offset counta函数

作者头像
全栈程序员站长
发布2022-10-02 11:37:45
发布2022-10-02 11:37:45
6720
举报

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

CountDownTimer类介绍

CountDownTimer类比较简单,总共就一个构造和4个方法。内部是通过handler实现

CountDownTimer(long time,long interval):参数time是总时间,interval是间隔时间

start():开始倒计时的方法

cancel():取消倒计时的方法

onTink(long time):抽象方法,每个间隔时间一到就会调用一次,需要自己实现。参数time是指剩下的时间

onFinish():抽象方法,倒计时完成的方法

CountDownTimer示例

效果图

主要代码MainActivity.java

代码语言:javascript
复制
public class MainActivity extends Activity { 

private TextView textView;
private MyCountDownTimer timer;
private final long TIME = 5 * 1000L;
private final long INTERVAL = 1000L;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView) findViewById(R.id.tv);
textView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
startTimer();
}
});
}
private class MyCountDownTimer extends CountDownTimer{ 

public MyCountDownTimer(long millisInFuture, long countDownInterval) {
super(millisInFuture, countDownInterval);
}
@Override
public void onTick(long l) {
long time = l / 1000;
textView.setEnabled(false);
textView.setText(time+"秒");
}
@Override
public void onFinish() {
textView.setEnabled(true);
textView.setText("重新发送");
cancelTimer();
}
}
/** * 开始倒计时 */
private void startTimer() {
if (timer == null) {
timer = new MyCountDownTimer(TIME, INTERVAL);
}
timer.start();
}
/** * 取消倒计时 */
private void cancelTimer() {
if (timer != null) {
timer.cancel();
timer = null;
}
}
@Override
protected void onDestroy() {
super.onDestroy();
cancelTimer();
}
}

存在的问题

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

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,再调用

textView.setText(time+”秒”);

textView为空,也就空指针了

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

总结

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

代码语言:javascript
复制
activity中
if(MainActivity.this.isFinishing()){
//doing something...
}
fragment中
if(getActivity()!=null){
//doing something...
}

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

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

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

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

源码下载

限于篇幅,只放了MainActivity的代码

布局是一个TextView,背景和文字通过设置selector来实现可点和不可点的效果

戳以下链接下载源码

http://download.csdn.net/download/u010356768/10243971

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

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

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

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

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • CountDownTimer类介绍
  • CountDownTimer示例
  • 存在的问题
  • 总结
  • 源码下载
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档