解决Android中CountDownTimer倒计时cancel方法无效的问题

来源:互联网 发布:河北知满天教育官网 编辑:程序博客网 时间:2024/06/12 12:33

一、概述

在项目中使用Android自带的CountDownTimer倒计时,在调用cancel方法时发现无法取消,onTick方法依然执行,百度一番,据说5.0以上才能正常cancel,5.0以下是没办法cancel的。

解决办法:在项目里使用5.0的CountDownTimer,把5.0里面的这个类拷贝到项目中,在代码里使用这个新拷贝的类,就可以解决问题了。

定义倒计时类

public class CountDown extends CountDownTimer {        public CountDown(long millisInFuture, long countDownInterval) {            super(millisInFuture, countDownInterval);        }        @Override        public void onFinish() {            updateDialog();        }        @Override        public void onTick(long millisUntilFinished) {            LogUtil.e("剩余 " + millisUntilFinished / 1000 + "秒");        }    }

调用倒计时

myCount = new CountDown(VALIDITY_TIME, 1000);        myCount.start();

从5.0系统拷贝过来新的CountDownTimer

package com.aldx.hccraftsman.utils;import android.os.Handler;import android.os.Message;import android.os.SystemClock;/* 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.        */public abstract class CountDownTimer {    /**     * Millis since epoch when alarm should stop.     */    private final long mMillisInFuture;    /**     * The interval in millis that the user receives callbacks     */    private final long mCountdownInterval;    private long mStopTimeInFuture;    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.     */    public CountDownTimer(long millisInFuture, long countDownInterval) {        mMillisInFuture = millisInFuture;        mCountdownInterval = countDownInterval;    }    /**     * Cancel the countdown.     *     * Do not call it from inside CountDownTimer threads     */    public final void cancel() {        mHandler.removeMessages(MSG);        mCancelled = true;    }    /**     * Start the countdown.     */    public synchronized final CountDownTimer start() {        if (mMillisInFuture <= 0) {            onFinish();            return this;        }        mStopTimeInFuture = SystemClock.elapsedRealtime() + mMillisInFuture;        mHandler.sendMessage(mHandler.obtainMessage(MSG));        mCancelled = false;        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();    private static final int MSG = 1;    // handles counting down    private Handler mHandler = new Handler() {        @Override        public void handleMessage(Message msg) {            synchronized (CountDownTimer.this) {                final long millisLeft = mStopTimeInFuture - SystemClock.elapsedRealtime();                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;                    if (!mCancelled) {                        sendMessageDelayed(obtainMessage(MSG), delay);                    }                }            }        }    };}

另外为防止程序奔溃,在activity销毁时加上这段代码:

@Override    protected void onDestroy() {        super.onDestroy();        if(myCount!=null){            myCount.cancel();        }    }
0 0