目录
一、简介
CountDownTimer是Android中的一个类,用于实现倒计时功能。通过CountDownTimer类,可以创建一个倒计时器,指定总倒计时时间以及每次倒计时的间隔时间。一旦倒计时开始,CountDownTimer会在指定的间隔时间内执行操作,直到倒计时结束。
1.1 CountDownTimer简介
CountDownTimer 是一个抽象类,包装了两个抽象方法onTick()和onFinish(),通常在使用的时候继承自CountDownTimer实现这两个抽象方法,内部封装了Handler,CountDownTimer是基于Handler实现的。
public abstract class CountDownTimer {
public CountDownTimer(long millisInFuture, long countDownInterval) {
mMillisInFuture = millisInFuture;
mCountdownInterval = countDownInterval;
}
/**
* 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();
......
1.2 常用API
CountDownTimer(long millisInFuture, long countDownInterval)
millisInFuture: 表示总的倒计时时间,以毫秒为单位。在倒计时结束之前,倒计时器将一直执行。
countDownInterval: 表示倒计时的间隔时间,以毫秒为单位。每隔这个时间间隔,onTick方法将会被调用一次。start():
作用:启动倒计时器,开始执行倒计时。
示例:countDownTimer.start();cancel():
作用:取消倒计时器,停止倒计时的执行。
示例:countDownTimer.cancel();onTick(long millisUntilFinished):
作用:在每次倒计时间隔结束时调用,用于执行更新UI等操作。
millisUntilFinished: 表示距离倒计时结束还有多少时间,以毫秒为单位。
示例:
new CountDownTimer(60000, 1000) {
public void onTick(long millisUntilFinished) {
textView.setText("Seconds remaining: " + millisUntilFinished / 1000);
}
public void onFinish() {
textView.setText(“Done!”);
}
}.start();onFinish():
作用:在倒计时结束时调用,用于执行最终的操作。
示例:
new CountDownTimer(60000, 1000) {
public void onTick(long millisUntilFinished) {
// Do something on tick
}
public void onFinish() {
textView.setText(“Done!”);
}
}.start();
二、CountDownTimer的用法
2.1 主线程中使用
Oncreate里使用
public static void test5() {
CountDownTimer countDownTimer = new CountDownTimer(1000L * 30, 1000L) {
@Override
public void onTick(long millisUntilFinished) {
// your logic for tick
Log.i("TEST", "onTick - " + Thread.currentThread() + ", id - " + Thread.currentThread().getId()+" "+millisUntilFinished);
}
@Override
public void onFinish() {
// your logic for finish
Log.i("TEST", "onFinish" + Thread.currentThread() + ", id - " + Thread.currentThread().getId());
}
};
countDownTimer.start();
}

回调执行在主线程,意味着可以在回调中直接处理UI,挺方便的。
2.2 工作线程中使用
在工作线程使用不能像在主线程一样简单使用,因为CountDownTimer是基于Handler的,主线程已经由安卓框架层启动了消息循环,可以直接使用。
那么在工作线程中怎样使用呢?可以借助HanderThread。在onLooperPrepared()中初始化并开启CountDownTimer:
public static void test6() {
new HandlerThread("TestThread") {
protected void onLooperPrepared() {
CountDownTimer countDownTimer = new CountDownTimer(1000L * 15, 1000L) {
@Override
public void onTick(long millisUntilFinished) {
// your logic for tick
Log.i("TEST", "onTick - " + Thread.currentThread() + ", id - " + Thread.currentThread().getId() + " " + millisUntilFinished);
}
@Override
public void onFinish() {
// your logic for finish
Log.i("TEST", "onFinish" + Thread.currentThread() + ", id - " + Thread.currentThread().getId());
}
};
countDownTimer.start();
}
}.start();
}

这一次运行在HandlerThread封装的TestThread线程中。
三、使用注意
3.1 空指针
空指针:当一个Activity或Fragment被销毁时,如果CountDownTimer的onTick()方法还在继续执行,而UI控件已经为空(比如Activity或Fragment的生命周期已经结束,UI控件已经被销毁),那么在onTick()方法中对UI控件的操作就会导致空指针异常。这是因为UI控件已经不存在,无法进行正常的操作。
解决办法:一般要在activity或fragment销毁的时候调用cancle方法。
@Override
protected void onDestroy() {
if (mCountDownTimer != null) {
mCountDownTimer.cancel();
}
super.onDestroy();
}
3.2 时间不是太准的问题
在CountDownTimer执行start后时,google源码里面减去了程序执行到这里的时候所消耗的时间
public void handleMessage(Message msg) {
synchronized (CountDownTimer.this) {
if (mCancelled) {
return;
}
final long millisLeft = mStopTimeInFuture - SystemClock.elapsedRealtime();
if (millisLeft <= 0) {
onFinish();
解决办法:
可以在构造方法里面稍微加一点时间就可以解决如60s
new CountDownTimer(60 * 1000+300, 1000)
3.3 内存泄漏问题
如果外部类在CountDownTimer执行期间被销毁,但CountDownTimer仍然持有对外部类的引用,这就会导致外部类无法被正常回收,从而引发内存泄漏。
解决办法:使用弱引用持有UI控件
WeakReference<TextView> tv;//控件软引用,防止内存泄漏
本文详细介绍了Android中的CountDownTimer类的使用方法,包括在主线程和工作线程的应用,同时讨论了空指针、时间准确性问题以及如何避免内存泄漏。

2733

被折叠的 条评论
为什么被折叠?



