CountDownTimer源码解析
作者:互联网
CountDownTimer适用于做倒计时,时间间隔一样的任务,比如5秒上传一次经纬度,这次我们看看它的源码。
1.初始化
countDownTimer = object : CountDownTimer(Long.MAX_VALUE, 1000) {
override fun onFinish() {}
override fun onTick(millisUntilFinished: Long) {
tv.text = millisUntilFinished.toString()
}
}
我们先看看这两个传参,第一个意思是 倒计时的总秒数,间隔时间
public CountDownTimer(long millisInFuture, long countDownInterval) {
mMillisInFuture = millisInFuture;
mCountdownInterval = countDownInterval;
}
2.启动
如果我们当初传 倒计时总秒数为0,就会直接走 onFinish,结束了此次倒计时。
最后给handler发送一个消息,这里说明这里倒计时是由Handler完成,看来间隔时间不会那么精准,甚至可能因为Handler消息过多而卡住。
public synchronized final CountDownTimer start() {
mCancelled = false;
if (mMillisInFuture <= 0) {
onFinish();
return this;
}
//算出结束倒计时的时间戳。
mStopTimeInFuture = SystemClock.elapsedRealtime() + mMillisInFuture;
mHandler.sendMessage(mHandler.obtainMessage(MSG));
return this;
}
我们看看这个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 {
//执行任务之前的时间戳
long lastTickStart = SystemClock.elapsedRealtime();
//触发一次间隔
onTick(millisLeft);
//onTick执行时间
long lastTickDuration = SystemClock.elapsedRealtime() - lastTickStart;
//延迟时间
long delay;
//如果剩余时间小于间隔时间,则是设置延迟时间为 剩余时间 减去 onTick执行时间
if (millisLeft < mCountdownInterval) {
delay = millisLeft - lastTickDuration;
if (delay < 0) delay = 0;
} else {
//若大于,延迟时间设置为 间隔时间减去onTick执行时间,这里算是在修正误差
delay = mCountdownInterval - lastTickDuration;
while (delay < 0) delay += mCountdownInterval;
}
//发送延迟消息,为下一次间隔任务做准备
sendMessageDelayed(obtainMessage(MSG), delay);
}
}
}
};
3.取消
就是清除消息,并设置mCancelled 为true,使还没有执行onTick的消息停止运行
public synchronized final void cancel() {
mCancelled = true;
mHandler.removeMessages(MSG);
}
4.总结
CountDownTimer主要使用Handler来完成时间间隔的计算,通过 计算onTick的执行时间,来去除误差,但是如果Handler本身Looper循环卡了,间隔任务还是会卡住
标签:synchronized,mCancelled,public,倒计时,Handler,解析,源码,CountDownTimer 来源: https://blog.csdn.net/z979451341/article/details/115175946