1

I found the code pasted below in a post on this forum back in 2011. I was using a timer to trigger the execution of doSomeWork but doSomeWork spawns an asynctask and (as I found out) asynctasks can only be spawned from the UI thread. So, I converted to using this postDelayed function of a Handler.

Now this code does indeed call doSomeWork every ten seconds and my asynctask no longer has problems. But when I call stopRepeatingTask() it does NOT stop the execution of doSomeWork - it keeps getting called every ten seconds.

This code is in a service and stopSelf() has been called but the code keeps running. The Android system doesn't even show the service as running but it's still calling doSomeWork.

What's wrong? How can I stop it? Thanks, Gary

private int m_interval = 5000; // 5 seconds by default, can be changed later
private Handler m_handler;

@Override
protected void onCreate(Bundle bundle) {
  // ...
  m_handler = new Handler();
}

Runnable m_statusChecker = new Runnable() {
     @Override 
     public void run() {
          doSomeWork(); //this function can change value of m_interval.
          m_handler.postDelayed(m_statusChecker, m_interval);
     }
};

void startRepeatingTask() {
    m_statusChecker.run(); 
}

void stopRepeatingTask() {
    m_handler.removeCallbacks(m_statusChecker); //  <--this does not appear to work
}
flx
  • 14,146
  • 11
  • 55
  • 70
Dean Blakely
  • 3,535
  • 11
  • 51
  • 83
  • http://stackoverflow.com/questions/5844308/removecallbacks-not-stopping-runnable – Johnny Z Sep 12 '13 at 22:51
  • The suggestion implementation is kind of more complicated than it needs to be. Instead, look at this: http://stackoverflow.com/questions/11981899/remove-callback-for-handler-not-work – Johnny Z Sep 12 '13 at 22:53
  • Basically make stopRunning() set a boolean flag, and check that flag before postDelayed() – Johnny Z Sep 12 '13 at 22:53
  • You should not call run directly. you should wrap it in a thread and then call start. Pls read. http://docs.oracle.com/javase/tutorial/essential/concurrency/runthread.html – prijupaul Sep 12 '13 at 22:54

1 Answers1

5

Add a status to your code to stop respawning new tasks:

private int mInterval = 5000; // 5 seconds by default, can be changed later
private Handler mHandler;
private boolean mIsRunning;

protected void onCreate(Bundle bundle) {
  // ...
  mHandler = new Handler();
}

Runnable mStatusChecker = new Runnable() {
     @Override 
     public void run() {
          if (!mIsRunning) {
              return; // stop when told to stop
          }
          doSomeWork(); // this function can change value of mInterval.
          mHandler.postDelayed(mStatusChecker, mInterval);
     }
};

void startRepeatingTask() {
    mIsRunning = true;
    mStatusChecker.run();
}

void stopRepeatingTask() {
    mIsRunning = false;
    mHandler.removeCallbacks(mStatusChecker);
}
flx
  • 14,146
  • 11
  • 55
  • 70
  • 1
    Notice that this shouldn't be needed if he were calling `removeCallbacks` in the Main thread. He probably has a worker thread and trying to stop the task from there. Or maybe he is calling that from `doSomeWork`. – Mister Smith Mar 15 '16 at 15:51