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

问题描述 投票:0回答:5

我有一个 “打开” 动画,并在短暂延迟后使用

Handler.postDelayed(Runnable, delay)
触发 “关闭” 动画。然而,在打开和关闭之间的时间里,可能会有另一个由点击触发的动画。

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

android handler runnable postdelayed
5个回答
109
投票

只需使用

removeCallbacks(Runnable r)
方法即可。


103
投票

Cristian 的答案是正确的,但与答案评论中所述相反,您实际上可以通过调用

Runnables
 来删除匿名 
removeCallbacksAndMessages(null);

的回调

此处所述:

删除任何 obj 为 token 的待处理回调帖子和已发送消息。 如果 token 为 null,所有回调和消息将被删除


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()),因此最好使用整数/整数而不是字符串作为令牌。


11
投票

如果您使用递归,您可以通过传递“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 并禁用倒计时。这仅对使用递归的人有用,但我来到这里寻找递归,所以我发布我的结果。


0
投票

如果您使用匿名可运行对象,您可以将其与令牌对象配对,以便稍后将其删除。

private void postDelayedRunnable(@NonNull Runnable runnable, @NonNull Object token, long delayMillis) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
        mHandler.postDelayed(runnable, token, delayMillis);
    } else {
        Message msg = Message.obtain(mHandler, runnable);
        msg.obj = token;
        mHandler.sendMessageDelayed(msg, delayMillis);
    }
}

要删除它,您需要相同的令牌并只需调用

mHandler.removeCallbacksAndMessages(token);

警告:将使用

==
而不是
.equals
方法来比较令牌。最好不要使用原始数据类型,请参阅:Android Handler 回调未删除令牌类型 Int 或 Long (*Kotlin)

© www.soinside.com 2019 - 2024. All rights reserved.