Created
November 2, 2015 12:06
-
-
Save Folyd/4067e0ad2096d12448fc to your computer and use it in GitHub Desktop.
IncrementTimer similar to CountdownTimer in android framework
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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