在Handler中执行所有已安排的(postDelayed)runnable

时间:2013-04-26 19:58:42

标签: android handler runnable android-handler

我使用处理程序,通过Runnable发布一些postDelayed(r, DELAY_TIME),但我需要在发布新Runnables之前执行所有postDelayed

如何实现这一目标的任何好主意?

编辑:

我希望它基本上像这样:

Runnable r = new Runnable() {
    // Do some fancy action
};

if (mHandler.runnablesScheduled) {
    mHandler.flushAllScheduledRunnables();
}
mHandler.postDelayed(r, DELAY);

3 个答案:

答案 0 :(得分:2)

在一个数组中,跟踪将要调用的runnables,然后,如果你想要它们被调用,取消postDelayed并直接调用runnables,只需从中调用run()方法来激活它们可运行的。示例代码:

// 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();

非常简单,我已对它进行了评论,以便您可以更好地理解它,但如果您不理解某些内容,请对其进行评论。您可以修改它以支持对同一个Runnable的多次调用,或者只是创建一个名为TrackingHandler的Handler的类扩展,并实现这些函数。

我现在正在编写代码,所以有可能是大量错别字,不知道。

答案 1 :(得分:0)

好吧,所有Runnable都在你的处理程序的队列中运行,所以如果你想在它的末尾运行一些东西,想到的最简单的方法是把它作为另一个{{ 1}}在队列中:

Runnable

答案 2 :(得分:0)

你需要一些东西来完成这项工作。

  1. 使用Handler.sendMessageDelayed(Message)代替Handler.postDelayed,并为what
  2. 分配有意义的Message
  3. 当您需要刷新队列时,请检查是否已将任何内容排队到Handler.hasMessages(int)。如果有任何内容,您可以使用Handler.removeMessages将其删除并自行执行。