removeCallbacks not stopping runnable
Handler.removeCallback
is synchronous and will work nicely provided:
- You call
postDelayed
always in the main thread. - You call
removeCallback
always in the main thread - You don't call
postDelayed
again after having removed callbacks.
So in your case removeCallbacks
is called from a button handler, which runs in the main thread. But you didn't show in your code the point from where you call postDelayed
. If you call it from a background thread thats where your problem is.
If you are sure you don't call any of these methods from background threads, and the order of the calls is correct, then you might be leaving uncancelled tasks unadvertedly alive due to activity recreation on config changes (screen rotation, etc). Always make sure to call removeCallbacks
again in the onDestroy
method to prevent this kind of problems.
It appears to me that removeCallbacks(..)
only stops pending messages (Runnables). If your runnable has already started, then there's no stopping it (at least not this way).
Alternatively, you can extend the Runnable class and give it some kind of kill switch like this:
public class MyRunnable implements Runnable
{
private boolean killMe = false;
private void run()
{
if(killMe)
return;
/* do your work */
}
private void killRunnable()
{
killMe = true;
}
}
This will only prevent it from starting, but you could occasionally check killMe
and bail out. If you are looping the runnable (like some kind of background thread) you can say:
while(!killMe) {
/* do work */
}
Hope this helps
EDIT I just wanted to post an update on this. Since this original post, Google has come up with a great class called AsyncTask that handles all of this stuff for you. Anyone reading this really should look into it because it is the correct way of doing things.
You can read about it here