Skip to content

Instantly share code, notes, and snippets.

@jamesonwilliams
Last active January 30, 2020 05:21
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 jamesonwilliams/5989696628c336ce2ade81be87738d22 to your computer and use it in GitHub Desktop.
Save jamesonwilliams/5989696628c336ce2ade81be87738d22 to your computer and use it in GitHub Desktop.
A timer that can be poked, to reset

Pinwheel Timer

This is named after the Pinwheel toy.

Another reasonable name might be "Resettable Timer."

You can picture spinning it. Before it stops spinning it, you help it to keep going, so that it won't stop.

final class PinwheelTimer {
  private final HandlerThread handlerThread;
  private final Handler countDownHandler;
  private final Runnable onTimedOut;
  private final long timeout;
 
  // Create a new pinwheel timer.
  PinwheelTimer(Runnable onTimedOut, long timeout) {
      this.handlerThread = new HandlerThread("PinwheelTimer");
      this.handlerThread.start();
      this.countDownHandler = new Handler(handlerThread.getLooper()); 
      this.onTimedOut = onTimedOut;
      this.timeout = timeout;
  }
  
  // Start the pinwheel timer.
  synchronized void start() {
      countDownHandler.postDelayed(onTimedOut, timeout);
  }
  
  // Stop the timer without calling back the aciton.
  // This instance cannot be used again.
  syncrhonized void stop() {
      countDownHandler.removeCallbacksAndMessages(null);
      handlerThread.quit();
  }
  
  // Reset the timer, without calling back the action.
  // The action will be called when the full original timeout elapses
  // beyond the time of this call.
  // This is the "pinwheel" part.
  syncrhonized void reset() {
      countDownHandler.removeCallbacksAndMessages(null);
      start();
  }
}

Usage

// Timer will never count down until started
PinwheelTimer timer = new PinwheelTimer(() -> Log.i(TAG, "Bam!"), 1_000);

// Timer will count down in 1_000ms (constructor arg)
timer.start();

// Wait for a bit
Thread.sleep(300);
// Timer has 700ms left.

timer.reset();
// timer will count down in 1_000 ms from now.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment