Timer with Pause and Resume Support – Android/Java

The CountDownTimer implementation of Android may not be suitable for all cases as the onTick() method of the CountDownTimer runs on the main/UI thread.

The same could also be achieved using a TimerTask, but we do not have support for Pause/Resume operations when you’re using a Timer and a TimerTask.

The following implementation of a generic Timer runs on a separate thread and hence is most suitable for any operation that does not involve UI updates. It is basically a wrapper around a Runnable scheduled with a ScheduledExecutorService which is part of the java.util.concurrent package. The following is a gist of the core Runnable that handles the tick.

future = execService.scheduleWithFixedDelay(new Runnable() {
	@Override
	public void run() {
		onTick();
		elapsedTime += Timer.this.interval;
		if (duration > 0) {
			if(elapsedTime >=duration){
				onFinish();
				future.cancel(false);
			}
		}
	}
}, 0, interval, TimeUnit.MILLISECONDS);

For pause, we cancel the Future instance that we obtained when we scheduled the Runnable using the ExecutorService.

future.cancel(false);

For resume, we just schedule the same Runnable again.

We leave the following methods as abstract, to force the classes extending the Timer class to override them.

/**
*	This method is called periodically with the interval set as the delay between subsequent calls.
*/
	protected abstract void onTick();

/**
* This method is called once the timer has run for the specified duration. If the duration was set as infinity, then   * this method is never called.
*/
	protected abstract void onFinish();

Following is an example implementation of a concrete class extending the abstract Timer:

public class ExampleTimer extends Timer{

	public ExampleTimer() {
		super();
	}

	public ExampleTimer(long interval, long duration){
		super(interval, duration);
	}

	@Override
	protected void onTick() {
		System.out.println("onTick called!");
	}

	@Override
	protected void onFinish() {
		System.out.println("onFinish called!");
	}

}

Following is a simple test showing the usage of the Timer.

//This creates a timer which will tick every second indefinitely.
Timer oneSecondInfiniteTimer = new ExampleTimer();

//This creates a timer which ticks every 2 seconds, and runs for 20 seconds.
Timer twoSecondTimer = new ExampleTimer(2000l, 20000l);

//Start the timer.
twoSecondTimer.start();

//Pause the timer.
twoSecondTimer.pause();

//Resume the timer
twoSecondTimer.resume();

The whole code is hosted in GitHub (https://github.com/c05mic/pause-resume-timer ) for your copy-pasting pleasure. 🙂

Contributions are welcome!

Advertisements