StuStirling
StuStirling

Reputation: 16221

Timer Not Stopping In Android

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.

Upvotes: 14

Views: 14437

Answers (9)

Saeid Mohammadi
Saeid Mohammadi

Reputation: 449

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();
        }
    }
}

Upvotes: 0

tahsinRupam
tahsinRupam

Reputation: 6396

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()

Upvotes: 0

Marlon
Marlon

Reputation: 1897

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
    }
}

Upvotes: 2

Immy
Immy

Reputation: 731

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.

Upvotes: 0

Ke Di
Ke Di

Reputation: 345

I know it's late but I also encountered this issue in my project, and hope my solution may give people some ideas. What I did in my project is as below:

Handler handler = new Handler();
    Runnable runnable = new Runnable() {
        @Override
        public void run() {
           //TODO Update UI
        }
    };

    public void stopTimer() {
        if (timer != null) {
            handler.removeCallbacks(runnable);
            timer.cancel();
            timer.purge();
            timer = null;
        }
    }

   public startTimer() {
            timer = new Timer();
            timer.schedule(new TimerTask() {
                @Override
                public void run() {
                    handler.post(runnable);
                }
            }, 0, 100);
       }

I think what's missed in previous answers is removeCallbacks.

Upvotes: 1

Smartop
Smartop

Reputation: 501

in the run() method, check if timer is null then

private TimerTask task = new TimerTask() {
@Override
public void run() {
if (timer == null)
	cancel();
...
}

cancel the operation.

Upvotes: 3

Mehul Santoki
Mehul Santoki

Reputation: 1208

Try this example....

     TimerTask mTimerTask;
    final Handler handler = new Handler();
    Timer t = new Timer();  
    int nCounter = 0;

//function for start timer
 public void doTimerTask()
    {

        mTimerTask = new TimerTask() 
        {
                public void run() 
                {
                        handler.post(new Runnable() 
                        {
                                public void run()
                                {

                                      nCounter++:       
                                    //your code
                                    .....
                                    ......

                                }
                       });
                }};

            // public void schedule (TimerTask task, long delay, long period) 
            t.schedule(mTimerTask,0,50);  // 

         }

         //function for stop timer
public void stopTimerTask(){

       if(mTimerTask!=null){

          Log.d("TIMER", "timer canceled");
          mTimerTask.cancel();
          nCounter = 0; 

     }

}    

//use above two function for start and stop timer.

Upvotes: 0

Sebastian Breit
Sebastian Breit

Reputation: 6159

if(waitTimer != null) {
   waitTimer.cancel();
   waitTimer.purge()
   waitTimer = null;
}

Upvotes: 1

Lucifer
Lucifer

Reputation: 29670

timer = new Timer("Message Timer"); 

Here your object timer is not a static so timer.cancel(); will cancel another instance of the Timer class. I suggest you to create a static instance variable of Timer Class on the top of the class, like below,

private static Timer timer;

Upvotes: 23

Related Questions