如何从处理程序中删除所有回调?
我的子活动中有一个由主活动调用的 Handler 活动。此处理程序由子类使用 postDelay
一些 Runnables,我无法管理它们。现在,在 onStop
事件中,我需要在完成 Activity 之前删除它们(不知何故我调用了 finish()
,但它仍然一次又一次地调用)。是否有办法从处理程序中删除所有回调?
I have a Handler from my sub-Activity that was called by the main Activity. This Handler is used by sub-classes to postDelay
some Runnables, and I can't manage them. Now, in the onStop
event, I need to remove them before finishing the Activity (somehow I called finish()
, but it still call again and again). Is there anyway to remove all callbacks from a Handler?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
根据我的经验,这非常有效!
在removeCallbacksAndMessages的文档中它说......
In my experience calling this worked great!
In the docs for removeCallbacksAndMessages it says...
对于任何特定的 Runnable 实例,调用 Handler.removeCallbacks()。请注意,它使用 Runnable 实例本身来确定要取消注册的回调,因此,如果您每次发布帖子时都创建一个新实例,则需要确保引用了确切的
Runnable
取消。示例:您可以调用 myHandler.postDelayed(myRunnable, x) 来将另一个回调发送到代码中其他位置的消息队列,并使用 myHandler.removeCallbacks(myRunnable) 删除所有挂起的回调 不幸的是
,即使您向
MessageQueue
对象发出请求,您也不能简单地“清除”Handler
的整个MessageQueue
与它关联是因为添加和删除项目的方法受包保护(只有 android.os 包中的类可以调用它们)。您可能需要创建一个精简的Handler
子类来管理发布/执行的Runnable
列表...或者查看另一种范例,用于在每个 Runnable 之间传递消息活动
希望有帮助!
For any specific
Runnable
instance, callHandler.removeCallbacks()
. Note that it uses theRunnable
instance itself to determine which callbacks to unregister, so if you are creating a new instance each time a post is made, you need to make sure you have references to the exactRunnable
to cancel. Example:You can call
myHandler.postDelayed(myRunnable, x)
to post another callback to the message queue at other places in your code, and remove all pending callbacks withmyHandler.removeCallbacks(myRunnable)
Unfortunately, you cannot simply "clear" the entire
MessageQueue
for aHandler
, even if you make a request for theMessageQueue
object associated with it because the methods for adding and removing items are package protected (only classes within the android.os package can call them). You may have to create a thinHandler
subclass to manage a list ofRunnable
s as they are posted/executed...or look at another paradigm for passing your messages between eachActivity
Hope that Helps!
定义一个新的处理程序并可运行:
延迟调用后:
从处理程序中删除回调:
Define a new handler and runnable:
Call post delayed:
Remove your callback from your handler:
请注意,应该在类作用域中定义一个
Handler
和一个Runnable
,以便它被创建一次。removeCallbacks(Runnable)
可以正常工作,除非人们多次定义它们。请查看以下示例以更好地理解:不正确的方式:
如果您调用
onClick(..)
方法,则在调用之前永远不会停止doIt()
方法的调用。因为每次都会创建新的 Handler 和新的 Runnable 实例。这样,您就丢失了属于 handler 和 runnable 实例的必要引用。正确的方法:
通过这种方式,您不会丢失实际引用,并且
removeCallbacks(runnable)
可以成功工作。关键句子是“在您使用的
Activity
或Fragment
中将它们定义为全局”。Please note that one should define a
Handler
and aRunnable
in class scope, so that it is created once.removeCallbacks(Runnable)
works correctly unless one defines them multiple times. Please look at following examples for better understanding:Incorrect way :
If you call
onClick(..)
method, you never stopdoIt()
method calling before it call. Because each time createsnew Handler
andnew Runnable
instances. In this way, you lost necessary references which belong to handler and runnable instances.Correct way :
In this way, you don't lost actual references and
removeCallbacks(runnable)
works successfully.Key sentence is that 'define them as global in your
Activity
orFragment
what you use'.如果您没有 Runnable 引用,则在第一个回调中获取消息的 obj,然后使用 removeCallbacksAndMessages() 删除所有相关回调。
If you don't have the Runnable references, on the first callback, get the obj of the message, and use removeCallbacksAndMessages() to remove all related callbacks.
正如
josh527
所说,handler.removeCallbacksAndMessages(null);
可以工作。但为什么呢?
如果你看一下源代码,你会更清楚地理解。
有 3 种类型的方法可以从处理程序(MessageQueue)中删除回调/消息:
Handler.java(保留一些重载方法)
MessageQueue.java do真正的工作:
As
josh527
said,handler.removeCallbacksAndMessages(null);
can work.But why?
If you have a look at the source code, you can understand it more clearly.
There are 3 type of method to remove callbacks/messages from handler(the MessageQueue):
Handler.java (leave some overload method)
MessageQueue.java do the real work:
这些解决方案都不适合我。但我找到了一个有效的解决方案。
即使在调用handler.removeCallbacksAndMessages(null)之后,已添加到处理程序队列中的可运行对象也会被执行。当我尝试停止线程时,导致错误:
W/MessageQueue(6436): java.lang.RuntimeException: Handler (android.os.Handler) {416659f0} sending message to a Handler on死线程
我的解决方案:
删除所有回调。你需要所有的参考
可以存储在 ArrayList 中的可运行对象。
然后每次你想发布一个可运行的文件时,将其存储在数组中,然后使用 handler.post() 发布数组项。
然后要删除所有回调,请使用此方法,该方法将通过迭代数组来删除每个回调。
布尔值allowPosting=true;
因此包括以下内容:
然后在处理程序中发布之前检查条件:
就这样,现在队列已清除,我们确信不再发布可运行的内容清除队列后。所以停止线程是安全的。
None of the solutions worked for me. But I found a solution that worked.
The runnables already added in the handler queue got executed even after calling
handler.removeCallbacksAndMessages(null)
. When I tried to stop the thread, it resulted in the error:W/MessageQueue(6436): java.lang.RuntimeException: Handler (android.os.Handler) {416659f0} sending message to a Handler on a dead thread
My solution:
To remove all the callbacks. you need the reference for all the
runnables which can be stored in an ArrayList.
Then every time u want to post a runnable, store it in the array, then post the array item using handler.post().
Then to remove all the callbacks use this method which will remove each callback by iterating through the array.
Hurray! the queue is cleared. But wait. After clearing the array we have to make sure that no more runnable is posted in the handler before you stop the thread. So you have to declare:
boolean allowPosting=true;
so include this:
Then check the condition before posting in the handler:
That's all, now the queue is cleared and we are sure that no more runnable is posted after clearing the queue. So it is safe to stop the thread.
文档说
removeCallbacksAndMessages(null)
删除所有回调,但并不总是如此。试试这个:The documentation says that
removeCallbacksAndMessages(null)
removes all callbacks, but it is not always true. Try this:删除特定可运行对象
删除所有可运行对象
To remove specific runnable
To remove all runnables