Android 倒计时器重写,实现可重复使用,动态修改计时时间
CountDownTimerRew 是一个可重写、动态修改计时时间的 Android 倒计时器类。它允许开发者设置倒计时总时长、间隔时间,并通过 onTick 和 onFinish 方法实现定时回调。该类支持动态修改计时参数,如 millisInFuture 和 countDownInterval,并提供了 cancel 和 start 方法控制计时器的启停。通过 WeakHandler 类,CountDownTimerRew 避免了内存泄漏问题。使用时,开发者只需继承该类并实现 onTick 和 onFinish 方法即可。
CountDownTimerRew 类
public abstract class CountDownTimerRew {
/**
* Millis since epoch when alarm should stop.
*/
private long mMillisInFuture;
/**
* The interval in millis that the user receives callbacks
*/
private long mCountdownInterval;
private long mStopTimeInFuture;
/**
* boolean representing if the timer was cancelled
*/
private boolean mCancelled = false;
private Object mTag;
/**
* @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, Object)} callbacks.
*/
public CountDownTimerRew(long millisInFuture, long countDownInterval) {
mMillisInFuture = millisInFuture;
mCountdownInterval = countDownInterval;
}
public CountDownTimerRew setTag(Object mTag) {
this.mTag = mTag;
return this;
}
public CountDownTimerRew setMillisInFuture(long mMillisInFuture) {
this.mMillisInFuture = mMillisInFuture;
return this;
}
public CountDownTimerRew setCountdownInterval(long mCountdownInterval) {
this.mCountdownInterval = mCountdownInterval;
return this;
}
/**
* Cancel the countdown.
*/
public synchronized final void cancel() {
mCancelled = true;
mHandler.removeMessages(MSG);
}
/**
* Start the countdown.
*/
public synchronized final CountDownTimerRew 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, Object mTag);
/**
* Callback fired when the time is up.
*/
public abstract void onFinish();
private static final int MSG = 1;
// handles counting down
private final Handler mHandler = new WeakHandler(Looper.getMainLooper()) {
@Override
public void handleMessage(@NonNull Message msg) {
synchronized (CountDownTimerRew.this) {
if (mCancelled) {
return;
}
final long millisLeft = mStopTimeInFuture - SystemClock.elapsedRealtime();
if (millisLeft <= 0) {
onFinish();
} else {
long lastTickStart = SystemClock.elapsedRealtime();
onTick(millisLeft, mTag);
// 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);
}
}
}
};
}
WeakHandler类
public class WeakHandler extends Handler {
private WeakReference<Activity> mActivity;
public WeakHandler() {
this(Looper.getMainLooper(), null);
}
public WeakHandler(@NonNull Looper looper) {
this(looper, null);
}
public WeakHandler(@NonNull Looper looper, Activity mActivity) {
super(looper);
setActivity(mActivity);
}
public WeakReference<Activity> getActivity() {
return mActivity;
}
public void setActivity(Activity mActivity) {
this.mActivity = new WeakReference<>(mActivity);
}
}
使用方法
private CountDownTimerRew mCountDownTimerRew;
public CountDownTimerRew getCountDownTimerRew() {
if (null == mCountDownTimerRew)
mCountDownTimerRew = new CountDownTimerRew(5000, 1000) {
@Override
public void onTick(long millisUntilFinished, Object mTag) {
int iSeconds = (int) (millisUntilFinished / 1000);
int iTag = mTag instanceof Integer ? (int) mTag : -1;
if (iTag == 0) {
//TODO
}
}
@Override
public void onFinish() {
}
};
return mCountDownTimerRew;
}
//启动计时器
getCountDownTimerRew().setMillisInFuture(180000).setMillisInFuture(500).setTag(0).start();
//取消计时器
getCountDownTimerRew().cancel();