6

我使用了一个处理程序,它发布了一些Runnablevia postDelayed(r, DELAY_TIME),但我需要Runnables在发布新的 via 之前执行所有操作postDelayed

任何好的想法如何尽可能简单地实现这一目标?

编辑:

我想要它基本上是这样的:

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

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

3 回答 3

3

在一个数组中,跟踪将要调用的可运行对象,然后,如果要调用它们,请取消 postDelayed 并直接调用可运行对象,只需调用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 并实现这些功能或其他东西。

我现在正在即时编写代码,所以可能有很多错别字,不知道。

于 2013-06-30T17:05:56.137 回答
0

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

mHandler.post(new Runnable() {
    @Override
    public void run() {
        mHandler.postDelayed(r, DELAY);
    }
});
于 2013-04-26T20:20:22.553 回答
0

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

  1. 使用Handler.sendMessageDelayed(Message)代替Handler.postDelayedwhat为您的Message
  2. 当您需要刷新队列时,请检查是否有任何内容已使用Handler.hasMessages(int). 如果有任何东西,您可以将其删除Handler.removeMessages并自己执行。
于 2013-04-28T18:59:13.340 回答