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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3627216/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 11:03:39  来源:igfitidea点击:

How to remove a runnable from a handler object added by postDelayed?

androidhandlerrunnablepostdelayed

提问by Bruce Lee

I have an "open"animation and am using Handler.postDelayed(Runnable, delay)to trigger a "close"animation after a short delay. However, during the time between open and close, there is possibly another animation triggered by a click.

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

My question is, how would I cancel the "close"animation in the handler?

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

回答by Cristian

Just use the removeCallbacks(Runnable r)method.

就用这个removeCallbacks(Runnable r)方法吧。

回答by Daniel L.

Cristian's answer is correct, but as opposed to what is stated in the answer's comments, you actually can remove callbacks for anonymous Runnablesby calling removeCallbacksAndMessages(null);

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

As stated here:

如前所述这里

Remove any pending posts of callbacks and sent messages whose obj is token. If token is null, all callbacks and messages will be removed.

删除任何挂起的回调和已发送的 obj 为令牌的消息。如果 token 为空,所有回调和消息将被删除

回答by NameSpace

This is a late answer, but here's a different method for when you only want to remove a specific category of runnables from the handler (i.e. in OP's case, just remove the close animation, leaving other runnables in the queue):

这是一个迟到的答案,但是当您只想从处理程序中删除特定类别的可运行对象时,这是一种不同的方法(即在 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);

The above code will execute "r3" and then "r4" only. This lets you remove a specific category of runnables defined by your token, without needing to hold any references to the runnables themselves.

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

Note: the source code compares tokens using the "==" operand only (it does not call .equals()), so best to use ints/Integers instead of strings for the token.

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

回答by robisaks

If your using recursion, you can acheive this by passing "this". See code below.

如果您使用递归,您可以通过传递“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);
}

This example will set the text of a TextView (timer) every second, counting down. Once it gets to 0, it will remove the the TextView from the UI and disable the countdown. This is only useful for someone who is using recursion, but I arrived here searching for that, so I'm posting my results.

这个例子将每秒设置一个 TextView(计时器)的文本,倒计时。一旦它变为 0,它将从 UI 中删除 TextView 并禁用倒计时。这仅对使用递归的人有用,但我来到这里是为了寻找它,所以我发布了我的结果。

回答by Karol Wasowski

If you want to remove the callback for an anonymous Runnable just run: handler = nullEverything will be removed.

如果您想删除匿名 Runnable 的回调,只需运行: handler = null一切都将被删除。