android中倒计时控件CountDownTimer分析 1 示例代码 new CountDownTimer(10000, 1000) { public void onTick(long millisUntilFinished) { LogUtil.i(TAG, "seconds remaining: " + millisUntilFinished / 1000); } public void onFinish() { LogUtil.i(TAG, "done!"); } }.start(); 2 API解析 CountDownTimer (long millisInFuture, long countDownInterval) millisInFuture: 你要倒计时的总时间, 单位ms. countDownInterval: 你要倒计时的间隔时间, 单位ms. public final void cancel () //取消当前的任务 public abstract void onFinish () //当前任务完成的时候回调 public abstract void onTick (long millisUntilFinished) //当前任务每完成一次倒计时间隔时间时回调 public final CountDownTimer start () //开始当前的任务 3 源码分析 public abstract class CountDownTimer { private final long mMillisInFuture; //倒计时的总时间 private final long mCountdownInterval; //倒计时的间隔时间 private long mStopTimeInFuture; private boolean mCancelled = false; //是否取消计时任务 //构造方法 public CountDownTimer(long millisInFuture, long countDownInterval) { mMillisInFuture = millisInFuture; mCountdownInterval = countDownInterval; } //取消倒计时 public synchronized final void cancel() { mCancelled = true; mHandler.removeMessages(MSG); } //开始倒计时 public synchronized final CountDownTimer start() { mCancelled = false; if (mMillisInFuture <= 0) { onFinish(); return this; } mStopTimeInFuture = SystemClock.elapsedRealtime() + mMillisInFuture; mHandler.sendMessage(mHandler.obtainMessage(MSG)); return this; } //定期会回调的方法 public abstract void onTick(long millisUntilFinished); //计时结束的回调方法 public abstract void onFinish(); private static final int MSG = 1; //CountDownTimer采用的是handler机制,通过sendMessageDelayed延迟发送一条message到主线程的looper中, //然后在自身中收到之后判断剩余时间,并发出相关回调,然后再次发出message的方式。 //取消倒计时,把任务从对MessageQueue中移除就好了。 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 if (millisLeft < mCountdownInterval) { sendMessageDelayed(obtainMessage(MSG), millisLeft); } else { long lastTickStart = SystemClock.elapsedRealtime(); onTick(millisLeft); long delay = lastTickStart + mCountdownInterval - SystemClock.elapsedRealtime(); while (delay < 0) delay += mCountdownInterval; sendMessageDelayed(obtainMessage(MSG), delay); } } } }; } 4 几点注意 1 elapsedRealtime currentTimeMillis()区别 System.currentTimeMillis()获取的是系统时间,是距离1970年1月1日开始计算的一个值; android.os.SystemClock.elapsedRealtime()获取从设备boot后经历的时间值。 System.currentTimeMillis()获取当前日期有意义,如当前是xxxx年xx月xx时xx分xx秒xxx毫秒,这个值在系统设置中可以更改的; 而SystemClock.elapsedRealtime()计算某个时间经历了多长时间有意义,例如通话经历了多长时间,这个值是系统设置无关。 但是Android源码中计算通话时间是用System.currentTimeMillis()的,这个一般情况下是没有问题的。 但是如果有人在设备建立通话后修改系统时间,那么通话结束后的时间值就不对了,日期往后调整个几年,通话时间就会显示有几年的 2 sendMessageDelayed() boolean sendEmptyMessageDelayed (int what, long delayMillis) 在特定的时间delayMillis流逝后 发送一个仅包含有what的消息
时间: 2024-12-20 03:13:49