Timer Not Stopping In Android

Viewed 12807

THE PROBLEM I am having problems stopping the Timer whilst developing in android.

The timer is already null when it comes to stopping it.

I then move the timer initialisation to outside of a method just like the TimerTask which solves the null problem but still doesn't cancel when timer.cancel(); is called upon it.

The code below is an example of the timer already being null when it comes to stopping the recording.

TimerTask

My TimerTask is initialized inside the class but outside of a method and the codes below...

private TimerTask task = new TimerTask() {
    @Override
    public void run() {
      Log.e("TRACK_RECORDING_SERVICE","Timer Running");
    }
  };

Timer & Timer Start

I then have a startRecroding method which is called when I want to start the timer...

public void startRecording(){
     timer = new Timer("Message Timer");
     timer.scheduleAtFixedRate(this.task, 0, 1000);
 }

Timer Stop

I then call the below method when I want to stop the timer...

public void stopRecording() {
     if (timer != null) {
         timer.cancel();
         timer = null;
     } else {
         Log.e("TRACK_RECORDING_SERVICE","Timer already null.");
     }
 }

Any help would be much appreciated.

9 Answers

Ok so the problem was in the instantiation not the actual stopping of the timer.

Everytime I called:

timer = Timer()
timer!!.scheduleAtFixedRate(object : TimerTask() {
    override fun run() {
       //something  
    }
}, delay, period)

It created another instance so the old instance was still running somewhere with no way to stop it.

So I just made sure to instantiate it when the timer is null so that no previous instance is getting pushed around and still running on the background.

if(timer == null) {
    timer = Timer()
    timer!!.scheduleAtFixedRate(object : TimerTask() {
        override fun run() {
            // something
        }
    }, delay, period)
}

Then just cancel it and set it to null.

fun stopTimer() {
    if (timer != null) {
        timer!!.cancel()
        timer!!.purge()
        timer = null
    }
}

Just in case if someone still comes here to find a solution to this problem, here is my experience.

I am running a timer in a service.

startForegroundService(mServiceIntent);

timer = new Timer();

When you refresh a service, you don't necessarily cancel it first, you just call startForegroundService(mServiceIntent); again. If you don't cancel the timer before you refresh the service, the original timer is still running in the background and calling methods even though you stop the timer in the refreshed new service.

So to sum it up, stop your timer before you refresh or update a background task. I hope it helps someone.

Though this is an old question, I've figured out an easy solution.

var timeTaskInstance : TimerTask ?= null

val task: TimerTask = object : TimerTask() {
      override fun run() {
           timeTaskInstance = this
           Log.e("TRACK_RECORDING_SERVICE", "Timer Running")
      }
 }

Now cancel timer from anywhere:

timeTaskInstance?.cancel()

I think you've canceled another instance of the timer. Your timer task would be better handled by a helper class.

public class TimerHelper {
    Timer timer;
    long InitialInMillis = 10 * 1000;
    long DelayInMillis = 2 * 60 * 1000; // 2 minutes

    public TimerHelper() {
        timer = new Timer();
        timer.schedule(new MyTimerTask(), InitialInMillis, DelayInMillis);
    }

    public void stopTimer() {
        if(timer != null){
            timer.cancel();
        }
    }

    class MyTimerTask extends TimerTask {
        @Override
        public void run() {
            // your task will be run every 2 minutes
            yourTask();
        }
    }
}
Related