如何从 postDelayed 添加的处理程序对象中删除可运行对象?
Posted
技术标签:
【中文标题】如何从 postDelayed 添加的处理程序对象中删除可运行对象?【英文标题】:How to remove a runnable from a handler object added by postDelayed? 【发布时间】:2011-04-07 08:00:09 【问题描述】:我有一个“打开” 动画,我正在使用Handler.postDelayed(Runnable, delay)
在短暂延迟后触发一个“关闭” 动画。但是,在打开和关闭之间的这段时间内,可能还有另一个由点击触发的动画。
我的问题是,如何取消处理程序中的 "close" 动画?
【问题讨论】:
如果您使用 Kotlin,请注意这个答案:***.com/a/30905295/2736039,我试过了,但遇到了这个问题(仅在 Kotlin 中):***.com/questions/62405834/… 【参考方案1】:只需使用removeCallbacks(Runnable r)
方法即可。
【讨论】:
是否可以删除匿名可运行对象的回调? 我不这么认为......你将不得不使用非匿名的。否则您以后将无法引用它们。 查看@NameSpace 的回答。如果您使用令牌发布可运行文件,则可以删除待处理的可运行文件。或者您可以使用 Daniel L. 的方法,使用 null 令牌删除所有回调/消息。 在 removeCallbacks(Runnable r) 不可用的情况下删除 API 的特定回调有什么建议吗? 这会删除所有出现的实例吗?因为我以不同的延迟时间多次发布它【参考方案2】:克里斯蒂安的回答是正确的,但与答案的 cmets 中所述相反,您实际上可以通过调用 removeCallbacksAndMessages(null);
来删除匿名 Runnables
的回调
如here所述:
删除所有待处理的回调和已发送消息,其 obj 为令牌。 如果 token 为空,所有的回调和消息都会被移除。
【讨论】:
我只想指出,无论您处理的是Handler
还是View
类,这种行为都是不同的。在View
类中(可能在4.0 之后?),您必须使用相同的Runnable
对象来取消任务,而对于Handler
类,如果您通过null
,它们将全部被取消。尽管如此,问题指定了Handler
,因此您的答案是正确的。
真的!!谢谢..那里有一些可运行的,而removeCallbacks什么也没做!!!!!!!但这确实有效:) thx【参考方案3】:
这是一个较晚的答案,但是当您只想从处理程序中删除特定类别的可运行文件时,这是一种不同的方法(即在 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()),因此最好使用整数/整数而不是字符串作为标记。
【讨论】:
我看到了你的答案,我从string
更改为int
然后我有一天这个错误:D ***.com/q/62405834/2736039
这在 Kotlin 中对于 int > 127 不起作用,只是将此评论留在这里作为对未来读者的提示【参考方案4】:
如果你使用递归,你可以通过传递“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 并禁用倒计时。这仅对使用递归的人有用,但我到这里是为了寻找它,所以我发布了我的结果。
【讨论】:
以上是关于如何从 postDelayed 添加的处理程序对象中删除可运行对象?的主要内容,如果未能解决你的问题,请参考以下文章
Android Studio - 如何从片段中停止 handler.postDelayed?
AsyncTask - 如何在AsyncTask中使用带有postDelayed(Runnable,int)的Handler?