Skip to content

Instantly share code, notes, and snippets.

@Folyd
Created November 2, 2015 12:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Folyd/4067e0ad2096d12448fc to your computer and use it in GitHub Desktop.
Save Folyd/4067e0ad2096d12448fc to your computer and use it in GitHub Desktop.
IncrementTimer similar to CountdownTimer in android framework
public abstract class IncrementTimer {
/**
* Millis since epoch when alarm should stop.
*/
private final long mMillisInFuture;
/**
* The interval in millis that the user receives callbacks
*/
private final long mIncrementInterval;
private long mMillisPassed;
/**
* 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 increment is done and {@link #onFinish()}
* is called.
* @param incrementInterval The interval along the way to receive
* {@link #onTick(long)} callbacks.
*/
public IncrementTimer(long millisInFuture, long incrementInterval) {
mMillisInFuture = millisInFuture;
mIncrementInterval = incrementInterval;
}
public IncrementTimer(long incrementInterval) {
this(Integer.MAX_VALUE, incrementInterval);
}
/**
* Cancel the increment.
*/
public synchronized final void cancel() {
mCancelled = true;
mHandler.removeMessages(MSG);
}
/**
* Start the increment.
*/
public synchronized final IncrementTimer start() {
mCancelled = false;
if (mMillisInFuture <= 0) {
onFinish();
return this;
}
mHandler.sendMessage(mHandler.obtainMessage(MSG));
return this;
}
/**
* Callback fired on regular interval.
*
* @param millisPassed The amount of time passed yet.
*/
public abstract void onTick(long millisPassed);
/**
* Callback fired when the time is up.
*/
public abstract void onFinish();
private static final int MSG = 1;
// handles time increment.
private Handler mHandler = new Handler(new Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {
synchronized (IncrementTimer.this) {
if (mCancelled) {
return true;
}
if (mMillisPassed < mMillisInFuture) {
long leftMillis = mMillisInFuture - mMillisPassed;
long delay;
if (leftMillis > mIncrementInterval) {
delay = mIncrementInterval;
} else {
delay = leftMillis;
}
mMillisPassed += delay;
onTick(mMillisPassed);
mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG), delay);
} else if (mMillisPassed >= mMillisInFuture) {
onFinish();
}
// final long millisLeft = mStopTimeInFuture - SystemClock.elapsedRealtime();
//
// if (millisLeft <= 0) {
// onFinish();
// } else if (millisLeft < mIncrementInterval) {
// // no tick, just delay until done
// mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG), millisLeft);
// } else {
// long lastTickStart = SystemClock.elapsedRealtime();
// onTick(millisLeft);
//
// // take into account user's onTick taking time to execute
// long delay = lastTickStart + mIncrementInterval - SystemClock.elapsedRealtime();
//
// // special case: user's onTick took more than interval to
// // complete, skip to next interval
// while (delay < 0) delay += mIncrementInterval;
//
// mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG), delay);
// }
return true;
}
}
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment