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


70

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

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


如果您使用Kotlin ,请仔细回答以下问题:stackoverflow.com/a/30905295/2736039,我尝试过这个问题,但遇到了这个问题(仅在Kotlin中):stackoverflow.com/questions/62405834/…–
Ultimo_m

Answers:


99

只需使用该removeCallbacks(Runnable r)方法即可。


10
是否可以删除匿名可运行对象的回调?
李小龙

10
我不这么认为...您将不得不使用非匿名密码。否则将来将无法引用它们。
克里斯蒂安(Cristian)

3
请参阅@NameSpace的答案。如果使用令牌发布可运行的对象,则可以删除它们。或者,您可以使用Daniel L.使用空令牌删除所有回调/消息的方法。
vman

对于删除removeCallbacks(Runnable r)不可用的API的特定回调,有什么建议吗?
gom1

这会删除该实例的所有实例吗?因为我多次将其发布,但延迟时间有所不同
Yeshu

96

克里斯蒂安(Cristian)的答案是正确的,但是与答案的注释相反,您实际上可以Runnables通过调用来删除匿名的回调removeCallbacksAndMessages(null);

如前所述这里

删除obj为令牌的回调和已发送消息的所有未决帖子。如果token为null,则将删除所有回调和消息


5
我只想指出,无论您处理的是HandlerAView类还是类,这种行为都是不同的。在一个View类中(也许在4.0之后?),您必须使用相同的Runnable对象来取消任务,而对于一个Handler类,如果您通过,它们将全部被取消null。但是,问题指定了一个,Handler因此您的答案是正确的。
2014年

1
真!!谢谢..那里有一些可运行的,和removeCallbacks只是什么都不做!但这确实有效:) thx
cV2 2014年

17

这是一个较晚的答案,但是当您只想从处理程序中删除特定类别的可运行对象时(例如,在OP的情况下,只需删除关闭动画,而将其他可运行对象保留在队列中),这是另一种方法:

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

上面的代码将只执行“ r3”,然后执行“ r4”。这使您可以删除由令牌定义的特定类别的可运行对象,而无需保留对可运行对象本身的任何引用。

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


我看到了您的回答,我从更改stringint,然后出现了一天的错误:D stackoverflow.com/q/62405834/2736039
Ultimo_m

对于int> 127,这在Kotlin中将不起作用,只是在此处留下此注释以提示将来的读者
Ultimo_m

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);
}

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.