Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

java.lang.IllegalStateException: TimerTask is scheduled already: Rationally using of Timer and TimerTask in Android

I write an application that connects to server and sends him ping commands, server answer with pong commands.

I want to implement connection timeout mechanism. I think it will be following:

  • Client send ping and start timer with timertask and delay
  • When client receive pong, timertask is cancelled.

Also, I want to optimize memory. So, not to recreate TimerTask every time I send ping command. I try code below:

private final Timer mSystemLogoutTimer = new Timer();
private final TimerTask mLogoutTask = new TimerTask() {

    @Override
    public void run() {
        mMessageInterface.onConnectionTimeout();
        cancel();
    }
};

private void ping() {
    sendRequest(RequestBuilder.formPing());
    mSystemLogoutTimer.schedule(mLogoutTask, CoreConst.PING_ANSWER_DELAY);
}

private void onPong() {
    mLogoutTask.cancel();
}

But I get following error when try to schedule TimerTask second time:

java.lang.IllegalStateException: TimerTask is scheduled already
at java.util.Timer.scheduleImpl(Timer.java:572)
at java.util.Timer.schedule(Timer.java:459)

I don't understand, because I call cancel() on TimerTask.

Please tell me what I am doing wrong. Thank you for answers!

like image 739
Artem Mostyaev Avatar asked May 14 '14 07:05

Artem Mostyaev


1 Answers

TimerTask.cancel() does not necessarily prevent the execution of the task. According to the SDK documentation, it returns true when the execution was actually prevented, false otherwise.

Looks like this it what happens with your code as the first time true is returned, but not the second, leading an IllegalStateException to be thrown when calling Timer.schedule() right after.

You should check TimerTask.cancel()'s return code, and recreate your TimerTask when false is returned: the TimerTask is burnt and cannot be reused at that stage.

like image 181
Shlublu Avatar answered Oct 12 '22 03:10

Shlublu