如何从postDelayed添加的处理程序对象中删除runnable?

Bru*_*Lee 65 android handler runnable postdelayed

我有一个"开放"的动画,Handler.postDelayed(Runnable, delay)用于在短暂延迟后触发"关闭"动画.但是,在打开和关闭之间的时间内,可能会有一个由点击触发的动画.

我的问题是,如何取消处理程序中的"关闭"动画?

Cri*_*ian 93

只需使用该removeCallbacks(Runnable r)方法.

  • 我不这么认为......你将不得不使用非匿名的.否则您将来无法参考它们. (9认同)
  • 是否可以删除匿名runnables的回调? (7认同)
  • 请参阅@ NameSpace的回答.如果使用令牌发布runnable,则可以删除挂起的runnable.或者您可以使用Daniel L.的方法使用空令牌删除所有回调/消息. (3认同)

Dan*_* L. 89

Cristian的答案是正确的,但与答案的评论中所说的相反,你实际上可以Runnables通过调用删除匿名的回调removeCallbacksAndMessages(null);

如前所述这里:

删除任何待处理的回调帖子并发送其obj为令牌的邮件.如果token为null,则将删除所有回调和消息.

  • 我只想指出,无论你是处理`Handler`还是`View`类,这种行为都是不同的.在`View`类中(也许在4.0之后?),你必须使用相同的`Runnable`对象来取消任务,而使用`Handler`类时,如果你传递`null`,它们将被取消.尽管如此,这个问题指定了一个"处理程序",所以你的答案是正确的. (4认同)

Nam*_*ace 16

这是一个迟到的答案,但是这里有一个不同的方法,当你只想从处理程序中删除特定类别的runnables时(即在OP的情况下,只需删除关闭动画,将其他runnables留在队列中):

    int firstToken = 5;
    int secondToken = 6;

    //r1 to r4 are all different instances or implementations of Runnable.  
    mHandler.postAtTime(r1, firstToken, 0);
    mHandler.postAtTime(r2, firstToken, 0);
    mHandler.postAtTime(r3, secondToken, 0);

    mHandler.removeCallbacksAndMessages(firstToken);

    mHandler.postAtTime(r4, firstToken, 0);
Run Code Online (Sandbox Code Playgroud)

上面的代码只执行"r3",然后执行"r4".这使您可以删除令牌定义的特定类别的runnable,而无需保留对runnable本身的任何引用.

注意:源代码仅使用"=="操作数比较令牌(它不调用.equals()),因此最好使用ints/Integers而不是令牌的字符串.


小智 10

如果你使用递归,你可以通过传递"this"来实现这一点.见下面的代码.

public void countDown(final int c){
    mHandler.postDelayed(new Runnable() {
        @Override
        public void run() {
            aq.id(R.id.timer).text((c-1)+"");
            if(c <= 1){
                aq.id(R.id.timer).gone();
                mHandler.removeCallbacks(this);
            }else{
                countDown(c-1);
            }
        }
    }, 1000);
}
Run Code Online (Sandbox Code Playgroud)

此示例将每秒设置TextView(计时器)的文本,倒计时.一旦达到0,它将从UI中删除TextView并禁用倒计时.这仅对使用递归的人有用,但我到达这里搜索,所以我发布了我的结果.