倒計(jì)時(shí)控件 CountDownTimer 用法和原理分析
本文轉(zhuǎn)載自微信公眾號(hào)「Android開(kāi)發(fā)編程」,作者Android開(kāi)發(fā)編程。轉(zhuǎn)載本文請(qǐng)聯(lián)系A(chǔ)ndroid開(kāi)發(fā)編程公眾號(hào)。
前言
關(guān)于倒計(jì)時(shí),有很多種寫(xiě)法,今天我們介紹一種Android自帶的倒計(jì)時(shí)控件CountDownTimer
一、CountDownTimer詳解
CountDownTimer:定時(shí)執(zhí)行在一段時(shí)間后停止的倒計(jì)時(shí),在倒計(jì)時(shí)執(zhí)行過(guò)程中會(huì)在固定間隔時(shí)間得到通知;
1、初始化和啟動(dòng)倒計(jì)時(shí)
- public CountTimer(long millisInFuture, long countDownInterval) {
- super(millisInFuture, countDownInterval);
- }
- @Override
- public void initData() {
- countDownTimer = new CountDownTimer(200000, 1000) {
- @Override
- public void onTick(long millisUntilFinished) {
- //單位天
- long day = millisUntilFinished / (1000 * 24 * 60 * 60);
- //單位時(shí)
- long hour = (millisUntilFinished - day * (1000 * 24 * 60 * 60)) / (1000 * 60 * 60);
- //單位分
- long minute = (millisUntilFinished - day * (1000 * 24 * 60 * 60) - hour * (1000 * 60 * 60)) / (1000 * 60);
- //單位秒
- long second = (millisUntilFinished - day * (1000 * 24 * 60 * 60) - hour * (1000 * 60 * 60) - minute * (1000 * 60)) / 1000;
- }
- /**
- *倒計(jì)時(shí)結(jié)束后調(diào)用的
- */
- @Override
- public void onFinish() {
- }
- };
- countDownTimer.start();
- }
- /**
- * 記得關(guān)閉,負(fù)責(zé)內(nèi)存溢出
- */
- @Override
- protected void onDestroy() {
- super.onDestroy();
- if (countDownTimer != null) {
- countDownTimer.cancel();
- countDownTimer = null;
- }
- }
2、參數(shù)和方法介紹
初始化參數(shù)
- millisInFuture 從開(kāi)始調(diào)用start()到倒計(jì)時(shí)完成并onFinish()方法被調(diào)用的毫秒數(shù)(倒計(jì)時(shí)時(shí)間,單位毫秒);
- countDownInterval 接收onTick(long)回調(diào)的間隔時(shí)間;
方法
- public final void cancel ()取消倒計(jì)時(shí)(取消后,再次啟動(dòng)會(huì)重新開(kāi)始倒計(jì)時(shí));
- public abstract void onFinish ()倒計(jì)時(shí)完成時(shí)被調(diào)用;
- public abstract void onTick (long millisUntilFinished)固定間隔被調(diào)用;
- 參數(shù) millisUntilFinished 倒計(jì)時(shí)剩余時(shí)間;
- public synchronized final CountDownTimer start ()啟動(dòng)倒計(jì)時(shí);
二、源碼注解
- import android.os.Handler;
- import android.os.Message;
- import android.os.SystemClock;
- /**
- * 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.
- */
- /**
- * customize from CountDownTimer
- * Created by zhubingning on 16/09/16.
- */
- public abstract class CustomCountDownTimer {
- /**
- * Millis since epoch when alarm should stop.
- */
- private final long mMillisInFuture;
- //!add,為了暫停時(shí)保存當(dāng)前還剩下的毫秒數(shù)
- private long mCurrentMillisLeft;
- /**
- * The interval in millis that the user receives callbacks
- */
- private final long mCountdownInterval;
- private long mStopTimeInFuture;
- /**
- * boolean representing if the timer was cancelled
- */
- private boolean mCancelled = false;
- /**
- * @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.
- */
- //構(gòu)造函數(shù),(總倒計(jì)時(shí)毫秒為單位,倒計(jì)時(shí)間隔)
- public CustomCountDownTimer(long millisInFuture, long countDownInterval) {
- mMillisInFuture = millisInFuture;
- mCountdownInterval = countDownInterval;
- }
- //!add, 獲取此時(shí)倒計(jì)時(shí)的總時(shí)間
- public long getCountTimes(){
- return mMillisInFuture;
- }
- /**
- * Cancel the countdown.
- */
- //取消倒計(jì)時(shí),handler從消息隊(duì)列里取出message
- public synchronized final void cancel() {
- mCancelled = true;
- mHandler.removeMessages(MSG);
- }
- /**
- * Pause the countdown.
- */
- //!add, 暫停,調(diào)用cancel()函數(shù), mCurrentMillisLeft為全局變量自動(dòng)保存
- public synchronized final void pause() {
- cancel();
- }
- /**
- * Resume the countdown.
- */
- //!add, 恢復(fù)函數(shù),根據(jù)mCurrentMillisLeft的值重新添加message開(kāi)始倒計(jì)時(shí)
- public synchronized final void resume() {
- mCancelled=false;
- if (mCurrentMillisLeft <= 0) {
- onFinish();
- return ;
- }
- mStopTimeInFuture = SystemClock.elapsedRealtime() + mCurrentMillisLeft;
- mHandler.sendMessage(mHandler.obtainMessage(MSG));
- return ;
- }
- /**
- * Start the countdown.
- */
- //開(kāi)始倒計(jì)時(shí),handler發(fā)送消息到隊(duì)列
- public synchronized final CustomCountDownTimer 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.
- */
- //虛擬函數(shù)
- public abstract void onTick(long millisUntilFinished);
- /**
- * Callback fired when the time is up.
- */
- //虛擬函數(shù)
- public abstract void onFinish();
- private static final int MSG = 1;
- // handles counting down
- //handler
- private Handler mHandler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- //同步線程
- synchronized (CustomCountDownTimer.this) {
- //判斷倒計(jì)時(shí)是否已取消
- if (mCancelled) {
- return;
- }
- //計(jì)算當(dāng)前剩余毫秒數(shù)
- final long millisLeft = mStopTimeInFuture - SystemClock.elapsedRealtime();
- //根據(jù)剩余毫秒數(shù),或者結(jié)束倒計(jì)時(shí),或者只延時(shí),或者調(diào)用onTick并延時(shí)
- if (millisLeft <= 0) {
- onFinish();
- } else if (millisLeft < mCountdownInterval) {
- // no tick, just delay until done
- onTick(0);//!add
- sendMessageDelayed(obtainMessage(MSG), millisLeft);
- } else {
- long lastTickStart = SystemClock.elapsedRealtime();
- mCurrentMillisLeft=millisLeft;//!add
- 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);
- }
- }
- }
- };
- }
總結(jié)
年底了,大家都很忙,大家都多多掙錢(qián),找個(gè)好工作,有什么問(wèn)題就發(fā)信息給我。