public abstract classCountDownTimer {/*** Millis since epoch when alarm should stop.*/
private final longmMillisInFuture;/*** The interval in millis that the user receives callbacks*/
private final longmCountdownInterval;private longmStopTimeInFuture;/*** boolean representing if the timer was cancelled*/
private boolean mCancelled = false;/***@parammillisInFuture The number of millis in the future from the call
* to {@link#start()} until the countdown is done and {@link#onFinish()}
* is called.
*@paramcountDownInterval The interval along the way to receive
* {@link#onTick(long)} callbacks.*/
public CountDownTimer(long millisInFuture, longcountDownInterval) {
mMillisInFuture=millisInFuture;
mCountdownInterval=countDownInterval;
}/*** Cancel the countdown.*/
public synchronized final voidcancel() {
mCancelled= true;
mHandler.removeMessages(MSG);
}/*** Start the countdown.*/
public synchronized finalCountDownTimer 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.
*@parammillisUntilFinished The amount of time until finished.*/
public abstract void onTick(longmillisUntilFinished);/*** Callback fired when the time is up.*/
public abstract voidonFinish();private static final int MSG = 1;//handles counting down
private Handler mHandler = newHandler() {
@Overridepublic voidhandleMessage(Message msg) {synchronized (CountDownTimer.this) {if(mCancelled) {return;
}final long millisLeft = mStopTimeInFuture -SystemClock.elapsedRealtime();if (millisLeft <= 0) {
onFinish();
}else if (millisLeft
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);
}
}
}
};
}