I use a Handler, which post some Runnable
via postDelayed(r, DELAY_TIME)
, but I need to execute all Runnables
before posting new via postDelayed
.
Any good ideas how to achieve this as simple as possible?
Edit:
I want it basically like this:
Runnable r = new Runnable() {
// Do some fancy action
};
if (mHandler.runnablesScheduled) {
mHandler.flushAllScheduledRunnables();
}
mHandler.postDelayed(r, DELAY);
In an Array, Keep track of runnables that are going to be called, then, if you want them to be called, cancel the postDelayed and call the runnables directly, to fire them just call the run()
method from the 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();
Is pretty easy and I've commented it so you can understand it better, but if you don't understand something, just comment it. You can modify it to support multiple calls to the same Runnable or just creating your own class extension of a Handler called TrackingHandler with these functions implemented or something.
I've written the code right now on the fly so is possible that is plenty of typos, don't know.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With