Android 计时器CountDownTimer延迟有关问题

Android 计时器CountDownTimer延迟问题

用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输出结果

Android 计时器CountDownTimer延迟有关问题

结果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;当然如果只是计时这是没问题的,如果执行固定次数反而会出问题。

版权声明:本文为博主原创文章,未经博主允许不得转载。