Clockplus/app/src/main/java/com/philliphsu/clock2/TickHandler.java
2016-06-07 13:16:53 -07:00

72 lines
2.2 KiB
Java

package com.philliphsu.clock2;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.SystemClock;
import android.support.annotation.NonNull;
import com.philliphsu.clock2.DurationDisplayer.OnTickListener;
import static com.philliphsu.clock2.util.Preconditions.checkNotNull;
/**
* Created by Phillip Hsu on 4/18/2016.
*/
public class TickHandler extends Handler {
private static final int MSG_TICK = 0;
private static final int MSG_FORCE_TICK = 1;
@NonNull private final OnTickListener mOnTickListener;
private final long mTickInterval;
public TickHandler(@NonNull OnTickListener listener, long tickInterval) {
super(Looper.getMainLooper());
mOnTickListener = checkNotNull(listener);
mTickInterval = tickInterval;
}
@Override
public void handleMessage(Message msg) {
// Account for the time showDuration() takes to execute
// and subtract that off from the countdown interval
// (so the countdown doesn't get postponed by however long
// showDuration() takes)
long startOnTick = SystemClock.elapsedRealtime();
mOnTickListener.onTick();
long countdownRemainder = mTickInterval -
(SystemClock.elapsedRealtime() - startOnTick);
// special case: onTick took longer than countdown
// interval to complete, skip to next interval
while (countdownRemainder < 0)
countdownRemainder += mTickInterval;
if (msg.what == MSG_TICK) { // as opposed to MSG_FORCE_TICK
sendMessageDelayed(obtainMessage(MSG_TICK), mTickInterval);
}
}
public void startTicking(boolean resume) {
if (hasMessages(MSG_TICK))
return;
if (resume) {
sendMessage(obtainMessage(MSG_TICK));
} else {
sendMessageDelayed(obtainMessage(MSG_TICK), mTickInterval);
}
}
public void stopTicking() {
removeMessages(MSG_TICK);
}
/**
* Forces a single call to {@link OnTickListener#onTick() onTick()}
* without scheduling looped messages on this handler.
*/
public void forceTick() {
sendMessage(obtainMessage(MSG_FORCE_TICK));
}
}