北京标准时间校准(北京标准时间校准毫秒 倒计时)
在Android 中倒计时功能是比较普遍使用的一个功能,比如手机验证码,计时执行命令等。实现方式有Handler、Thread 等,但是实现起来都比较复杂,过于麻烦,需要自己去写很多代码。今天讲讲在Android中如何用CountDownTimer 非常简单的实现倒计时功能。
先看看CountDownTimer 类源码,我们先来熟悉它的构造,再动手。CountDownTimer 实现倒计时功能的机制也是用Handler 消息控制,只是它帮我们已经封装好了,我们可以直接实现类提供的方法就可以写自己的业务逻辑了。下面先从该类的描述看起。
/*** Schedule a countdown until a time in the future, with* regular notifications on intervals along the way.** Example of showing a 30 second countdown in a text field:** <pre class="prettyprint">* new CountDownTimer(30000, 1000) {** public void onTick(long millisUntilFinished) {* mTextField.setText("seconds remaining: " + millisUntilFinished / 1000);* }** public void onFinish() {* mTextField.setText("done!");* }* }.start();* </pre>** The calls to {@link #onTick(long)} are synchronized to this object so that* one call to {@link #onTick(long)} won't ever occur before the previous* callback is complete. This is only relevant when the implementation of* {@link #onTick(long)} takes an amount of time to execute that is significant* compared to the countdown interval.*/
大致描述是 设置一个倒计时时间,直到完成一个时间段的计时,并且会时时更新时间的变化,举了一个30秒倒计时的例子如下
new CountDownTimer(30000, 1000) { public void onTick(long millisUntilFinished) { mTextField.setText("seconds remaining: " + millisUntilFinished / 1000); } public void onFinish() { mTextField.setText("done!"); } }.start();
从这个例子中可以看出,他有一个构造方法,传入了两个参数。
/** * @param millisInFuture The number of millis in the future from the call * to {@link #start()} until the countdown is done and {@link #onFinish()} * is called. * @param countDownInterval The interval along the way to receive * {@link #onTick(long)} callbacks. */ public CountDownTimer(long millisInFuture, long countDownInterval) { mMillisInFuture = millisInFuture; mCountdownInterval = countDownInterval; }
第一个参数传入设置倒计时的总时间,第二个参数传入每隔多少毫秒执行一次,注意这里传入的两个时间参数的单位都是毫秒。如我要定义一个一分的倒计时,每隔一秒执行一次,传参时就应该是 new CountDownTimer(60000, 1000)。
下面看看提供的这几个方法。
/** * Cancel the countdown. */ public synchronized final void cancel() { mCancelled = true; mHandler.removeMessages(MSG); } /** * Start the countdown. */ public synchronized final CountDownTimer start() { mCancelled = false; if (mMillisInFuture <= 0) { onFinish(); return this; } mStopTimeInFuture = SystemClock.elapsedRealtime() + mMillisInFuture; mHandler.sendMessage(mHandler.obtainMessage(MSG)); return this; } /** * 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();
cancel() 从字面上也理解到,它就是取消倒计时的意思.通过Handler removeMessages 取消正在执行的倒计时任务。start() 开始执行倒计时。通过Handler sendMessage 发送消息并开始执行倒计时任务。onTick() 倒计时更新。这里可以得到距离完成倒计时还剩多少时间。onFinish() 倒计时完成后的回调。
我们再来看看Handler 实现部分
// handles counting down 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); // take into account user's onTick taking time to execute long lastTickDuration = SystemClock.elapsedRealtime() – lastTickStart; long delay; if (millisLeft < mCountdownInterval) { // just delay until done delay = millisLeft – lastTickDuration; // special case: user's onTick took more than interval to // complete, trigger onFinish without delay if (delay < 0) delay = 0; } else { delay = mCountdownInterval – lastTickDuration; // special case: user's onTick took more than interval to // complete, skip to next interval while (delay < 0) delay += mCountdownInterval; } sendMessageDelayed(obtainMessage(MSG), delay); } } } };
这里主要是轮询计算时间,调用 onTick() 方法更新当前倒计时时间,当mStopTimeInFuture 减去 SystemClock.elapsedRealtime()(boot 以来经过的毫秒数)小于等于 0 时 ,则调用 onFinish()。
下面我们简单写一个实现倒计时的demo 为了代码维护和重用,我这里写一个公共的倒计时 CommonCountDownTimer 类,代码如下:
import android.os.CountDownTimer;/** * 公共倒计时类 */public class CommonCountDownTimer extends CountDownTimer { private OnCountDownTimerListener countDownTimerListener; public void setCountDownTimerListener(OnCountDownTimerListener listener) { this.countDownTimerListener = listener; } /** * @param millisInFuture The number of millis in the future from the call * to {@link #start()} until the countdown is done and {@link #onFinish()} * is called. * @param countDownInterval The interval along the way to receive * {@link #onTick(long)} callbacks. */ public CommonCountDownTimer(long millisInFuture, long countDownInterval) { super(millisInFuture, countDownInterval); } @Override public void onTick(long millisUntilFinished) { if (null != countDownTimerListener) { countDownTimerListener.onTick(millisUntilFinished); } } @Override public void onFinish() { if (null != countDownTimerListener){ countDownTimerListener.onFinish(); } } public interface OnCountDownTimerListener { /** * 更新倒计时时间 * * @param millisUntilFinished */ void onTick(long millisUntilFinished); /** * 完成倒计时 */ void onFinish(); }}
这里的CommonCountDownTimer 类继承了 android.os.CountDownTimer 类,我定义了一个 OnCountDownTimerListener 接口主要来监听 onTick(long millisUntilFinished) 和 onFinish() ,这样可以把业务逻辑分开来处理。
开始使用
private void initCountDownTimer() { mCountDownTimer = new CommonCountDownTimer(60000, 1000); mCountDownTimer.setCountDownTimerListener(new CommonCountDownTimer.OnCountDownTimerListener() { @Override public void onTick(long millisUntilFinished) { tv_time.setText("倒计时:" + millisUntilFinished / 1000); } @Override public void onFinish() { tv_time.setText("倒计时: 00"); } }); }
就是这么简单,主要需要理解 CountDownTimer 这个类,理解了之后就可以根据自己的业务场景灵活使用了。由于本人很菜,有些地方认识理解不对的地方欢迎,谢谢大家指正。
题图: pixabay
如发现本站有涉嫌抄袭侵权/违法违规等内容,请联系我们举报!一经查实,本站将立刻删除。