Execute all scheduled (postDelayed) runnables in the handler

I use a handler that dispatches Runnable via postDelayed(r, DELAY_TIME) , but I need to execute all Runnables before publishing a new one via postDelayed .

Any good ideas how to achieve this as easy as possible?

Edit:

I want this basically like this:

 Runnable r = new Runnable() { // Do some fancy action }; if (mHandler.runnablesScheduled) { mHandler.flushAllScheduledRunnables(); } mHandler.postDelayed(r, DELAY); 
+4
source share
3 answers

In the array, keep track of the calls that will be called, then if you want to be called, cancel postDelayed and call runnables directly to run them, just call the run() method from runnable, Example code:

 // Declaring the Handler and the Array that is going to track Runnables going to be tracked. final mHandler = new Handler(); final List<Runnable> callStack = new ArrayList<Runnable>(); // Method to remove a runnable from the track Array. public void removePostDelayed(Runnable run) { callStack.remove(run); } // Method that we use in exchange of mHandler.postDelayed() public void myPostDelayed(Runnable run, int delay) { // I remove callbacks because I don't know if can be called 2 times. mHandler.removeCallbacks(run); // We remove the Runnable from the tracking Array just in case we are going to add a Runnable that has not been called yet. removePostDelayed(run); // We add the runnable to the tracking Array and then use postDelayed() callStack.add(run); mHandler.postDelayed(run, delay); } // This is the Runnable. IMPORTANT: Remember to remove the Runnable from the tracking Array when the Runnable has been called. Runnable myRunnable = new Runnable() { @Override public void run() { // Do some fancy stuff and remove from the tracking Array. removePostDelayed(this); } } // Method to execute all Runnables public void callAllStack() { // We create a copy of the tracking Array because if you modify the Array while you are iterating through it, will return an Exception. List<Runnable> callStackCopy = new ArrayList<Runnable>(); // here we copy the array and remove all callbacks, so they are not called by the Handler. for (Runnable runnable : callStack) { callStackCopy.add(runnable); mHandler.removeCallbacks(runnable); } // Then we call all the Runnables from the second Array for (Runnable runnable : callStackCopy) { runnable.run(); } // And clear the tracking Array because the Handler has no more Runnables to call (This is redundant because supposedly each run() call removes himself from the tracking Array, but well... just in case we forgot something). callStack.clear(); } // Example of postDelaying a Runnable while tracking if has been fired. myPostDelayed(myRunnable, 1000) // Example of firing all Runnables. callAllStack(); 

Pretty easy, and I commented on it so that you can understand it better, but if you do not understand something, just comment on it. You can change it to support multiple calls of the same Runnable, or simply create your own TrackingHandler handler class extension with implemented functions or something.

I wrote the code right now on the fly, so it’s possible that there are a lot of typos, I don’t know.

+1
source

Well, all Runnable are run in a queue in your handler, so if you want to run something at the end of this, the easiest way that comes to mind is to put it as another Runnable on the queue:

 mHandler.post(new Runnable() { @Override public void run() { mHandler.postDelayed(r, DELAY); } }); 
0
source

You need a few things to make this work.

  • Use Handler.sendMessageDelayed(Message) instead of Handler.postDelayed and assign what your Message
  • When you need to drop the queue, check if everything is already queued using Handler.hasMessages(int) . If there is anything, you can delete it using Handler.removeMessages and execute it yourself.
0
source

All Articles