注意: 需要在主线程里调用 .start()
,否则没效果
import android.os.Handler;
import android.os.Looper;
/**
* Created by dongqi on 2021/12/21.
*/
public class MCountDownTimer {
private static final String TAG = MCountDownTimer.class.getSimpleName();
private MyCountDownTimerCompat countDownTimer;
private long mMillisInFuture;
private long mCountDownInterval;
private Handler mainHandler = new Handler(Looper.getMainLooper());
/**
* 不是单例,每次都会创建新对象 (CountDownTimer)
* @return
*/
public static MCountDownTimer getCountDownTimer(){
return new MCountDownTimer() ;
}
/**
* 总时长
* @param millisInFuture
* @return
*/
public MCountDownTimer setMillisInFuture(long millisInFuture){
mMillisInFuture = millisInFuture;
return this;
}
/**
* 间隔时长
* @param countDownInterval
* @return
*/
public MCountDownTimer setCountDownInterval(long countDownInterval){
mCountDownInterval = countDownInterval;
return this;
}
OnTickCallback mOnTickCallback;
public MCountDownTimer setOnTick(OnTickCallback onTickCallback){
mOnTickCallback = onTickCallback;
return this;
}
public interface OnTickCallback{
void onTick(long millisUntilFinished) ;
}
public interface OnFinishCallback{
void onFinish() ;
}
public interface OnCancelCallback{
void onCancel() ;
}
OnCancelCallback mOnCancelCallback;
public MCountDownTimer setOnCancel(OnCancelCallback onCancelCallback){
mOnCancelCallback = onCancelCallback;
return this;
}
OnFinishCallback mOnFinishCallback;
public MCountDownTimer setOnFinish(OnFinishCallback onFinishCallback){
mOnFinishCallback = onFinishCallback;
return this;
}
public MCountDownTimer() {
if (mainHandler == null)
mainHandler = new Handler(Looper.getMainLooper());
}
/**
* 创建 CountDownTimer ,并调用 start 函数
*/
public void start(){
L.d(TAG," start 1");
L.d(TAG," start 1 mMillisInFuture = "+mMillisInFuture);
L.d(TAG," start 1 mCountDownInterval = "+mCountDownInterval);
if (mainHandler == null)
throw new NullPointerException("start() 中的 mainHandler 是 null!!! ");
mainHandler.post(new Runnable() {
@Override
public void run() {
countDownTimer = new MyCountDownTimerCompat(mMillisInFuture,mCountDownInterval) {
@Override
public void onTick(long millisUntilFinished) {
L.d(TAG," onTick millisUntilFinished ="+millisUntilFinished);
if (mOnTickCallback!= null)
mOnTickCallback.onTick(millisUntilFinished);
}
@Override
public void onFinish() {
L.d(TAG," onFinish ");
if (mOnFinishCallback!=null)
mOnFinishCallback.onFinish();
}
@Override
public void onCancel() {
if (mOnCancelCallback!=null)
mOnCancelCallback.onCancel();
}
};
if (countDownTimer == null) {
L.d(TAG," start 2 countDownTimer null !!!");
}else {
countDownTimer.start();
}
L.d(TAG," start 2");
}
});
}
public void cancel(){
if (countDownTimer != null) {
mainHandler.post(new Runnable() {
@Override
public void run() {
countDownTimer.cancel();
}
});
}
}
}
因为android5.0以下,取消函数没有效果,所以复制了一份CountDownTimer高版本的源码出来到放到 MyCountDownTimerCompat 里;并且增加啦 onCancel回调接口
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
import java.lang.ref.WeakReference;
/**
* Created by wanghh on 16/9/6.
*/
public abstract class MyCountDownTimerCompat {
/**
* Millis since epoch when alarm should stopSpeaking.
*/
private final long mMillisInFuture;
/**
* 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.
*/
public MyCountDownTimerCompat(long millisInFuture, long countDownInterval) {
mMillisInFuture = millisInFuture;
mCountdownInterval = countDownInterval;
}
/**
* Cancel the countdown.
*/
public synchronized final void cancel() {
mCancelled = true;
mHandler.removeMessages(MSG);
}
/**
* Start the countdown.
*/
public synchronized final MyCountDownTimerCompat 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();
public abstract void onCancel();
private static final int MSG = 1;
static class MyHandler extends Handler {
private WeakReference<MyCountDownTimerCompat> mOuter;
public MyHandler(MyCountDownTimerCompat myCountDownTimerCompat) {
mOuter = new WeakReference<MyCountDownTimerCompat>(myCountDownTimerCompat);
}
@Override
public void handleMessage(Message msg) {
MyCountDownTimerCompat outer = mOuter.get();
if (null != outer) {
synchronized (MyCountDownTimerCompat.class) {
if (outer.mCancelled) {
outer.onCancel();
return;
}
final long millisLeft = outer.mStopTimeInFuture - SystemClock.elapsedRealtime();
if (millisLeft <= 0) {
outer.onFinish();
} else if (millisLeft < outer.mCountdownInterval) {
// no tick, just delay until done
sendMessageDelayed(obtainMessage(MSG), millisLeft);
} else {
long lastTickStart = SystemClock.elapsedRealtime();
outer.onTick(millisLeft);
// take into account user's onTick taking time to execute
long delay = lastTickStart + outer.mCountdownInterval - SystemClock.elapsedRealtime();
// special case: user's onTick took more than interval to
// complete, skip to next interval
while (delay < 0) delay += outer.mCountdownInterval;
sendMessageDelayed(obtainMessage(MSG), delay);
}
}
}
// super.handleMessage(msg);
}
}
private MyHandler mHandler = new MyHandler(MyCountDownTimerCompat.this);
// handles counting down
// private Handler mHandler = new Handler() {
//
// @Override
// public void handleMessage(Message msg) {
//
// synchronized (MyCountDownTimer.this) {
// if (mCancelled) {
// onCancel();
// return;
// }
//
// 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;
//
// sendMessageDelayed(obtainMessage(MSG), delay);
// }
// }
// }
// };
}
网友评论