用CountDownTimer作验证码倒计时计时器时,最后执行onfinish()时,会有不到一秒的延迟问题,比如
new CountDownTimers(10*1000,1000) {
@Override
public void onTick(long millisUntilFinished) {
// TODO Auto-generated method stub
System.out.println(millisUntilFinished/1000+"");
}
@Override
public void onFinish() {
// TODO Auto-generated method stub
System.out.println("finish");
}
}.start();
执行这段代码,如果不考虑执行延迟,那么结果应该是10,9,8,7,6,5,4,3,2,1,finish;
但是由于执行延迟的原因,结果就是 9,8,7,6,5,4,3,2,1,finish;并且最后 执行finish时会有不到1秒的延迟,下面看源码
// handles counting down
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
synchronized (CountDownTimer.this) {
final long millisLeft = mStopTimeInFuture - SystemClock.elapsedRealtime();
Log.e("left", millisLeft+"");
if (millisLeft <= 0) {
onFinish();
} else if (millisLeft < mCountdownInterval) {
// no tick, just delay until done
sendMessageDelayed(obtainMessage(MSG), millisLeft);
} else {
long lastTickStart = SystemClock.elapsedRealtime();
onTick(millisLeft);
// take into account user's onTick taking time to execute
long delay = lastTickStart + mCountdownInterval - SystemClock.elapsedRealtime();
// special case: user's onTick took more than interval to
// complete, skip to next interval
while (delay < 0) delay += mCountdownInterval;
sendMessageDelayed(obtainMessage(MSG), delay);
}
}
}
};
代码中第9行我添加了log输出剩余时间,查看log输出结果
结果982之前的输出对应ontick()的9,8,7,6,5,4,3,2,1。
但是到982时就出问题了,由于执行延迟问题,本应为1000,结果却是982,也就走到了源码的
else if (millisLeft < mCountdownInterval) {
// no tick, just delay until done
sendMessageDelayed(obtainMessage(MSG), millisLeft);
}
这样982时就没有执行ontick,反而延后982执行onfinish,也就是说从ontick输出1到执行onfinish中间的间隔为1985+2,也就是少执行了一次ontick,这就导致最后一秒到结束有一秒左右的延迟时间,会稍微有一点卡顿;当然如果只是计时这是没问题的,如果执行固定次数反而会出问题。