7

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!

Artem Mostyaev
  • 3,874
  • 10
  • 53
  • 60

1 Answers1

12

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.

Shlublu
  • 10,917
  • 4
  • 51
  • 70
  • Ok, thanks! Try to write memory optimized code for Android fails :) – Artem Mostyaev May 14 '14 at 08:30
  • How you think, it is right to start timertask to detect ping timeout? – Artem Mostyaev May 14 '14 at 08:31
  • 2
    Well, regarding the optimization it depends: some memory optimization can be really useful sometimes. But it is a good practice to first have something that works (even as a prototype), and then to try to implement it in a way it would consume as less CPU or memory resources as possible. Provided the gain is relevant. There is no need to spend days on something that would lead to a gain of 2ms each time the user fills a form, for example. Regarding the ping timout design, I have nothing to say as as don't know the context enough. – Shlublu May 14 '14 at 08:54
  • 1
    Thank you for explanation, I agree with you. Lets close this discussion :) Thank you again! – Artem Mostyaev May 14 '14 at 08:56