我的子活动中有一个Handler,由主Activity调用。这个Handler被子类用于postDelay
一些Runnables,我无法管理它们。现在,在onStop
事件中,我需要在完成活动之前删除它们(不知何故我调用finish()
,但它仍然一次又一次地调用)。无论如何要从处理程序中删除所有回调吗?
答案 0 :(得分:477)
根据我的经验,这称之为很有效!
handler.removeCallbacksAndMessages(null);
在removeCallbacksAndMessages的文档中,它说......
删除任何待处理的回调帖子,并发送obj为令牌的邮件。 如果令牌为
null
,则系统会删除所有回调和消息。
答案 1 :(得分:18)
对于任何特定的Runnable
个实例,请致电Handler.removeCallbacks()
。请注意,它使用Runnable
实例本身来确定要取消注册的回调,因此如果您每次发布帖子时都要创建新实例,则需要确保引用了完整的Runnable
取消。例如:
Handler myHandler = new Handler();
Runnable myRunnable = new Runnable() {
public void run() {
//Some interesting task
}
};
您可以致电myHandler.postDelayed(myRunnable, x)
向代码中其他位置的邮件队列发送另一个回调,并使用myHandler.removeCallbacks(myRunnable)
删除所有待处理的回调
不幸的是,您不能简单地“清除”MessageQueue
的整个Handler
,即使您请求与其关联的MessageQueue
对象,因为添加和删除的方法也是如此items受包保护(只有android.os包中的类可以调用它们)。您可能必须创建一个瘦Handler
子类来管理Runnable
列表的发布/执行...或者查看另一个范例,以便在每个Activity
之间传递您的消息/ p>
希望有帮助!
答案 2 :(得分:8)
如果您没有Runnable引用,请在第一个回调中获取消息的obj,并使用removeCallbacksAndMessages()删除所有相关的回调。
答案 3 :(得分:5)
定义一个新的处理程序和runnable:
private Handler handler = new Handler(Looper.getMainLooper());
private Runnable runnable = new Runnable() {
@Override
public void run() {
// Do what ever you want
}
};
致电邮件延迟:
handler.postDelayed(runnable, sleep_time);
从处理程序中删除回调:
handler.removeCallbacks(runnable);
答案 4 :(得分:2)
实际上这里有一点但非常重要的一点。
您应该第一次定义Handler
和Runnable
。实际上removeCallbacks(runnable)
正常工作但如果你每次都定义它们,你可能无法处理它们。
错误的方式:
public class FooActivity extends Activity {
private void handleSomething(){
Handler handler = new Handler();
Runnable runnable = new Runnable() {
@Override
public void run() {
doIt();
}
};
if(shouldIDoIt){
//doIt() works after 3 seconds.
handler.postDelayed(runnable, 3000);
} else {
handler.removeCallbacks(runnable);
}
}
public void onClick(View v){
handleSomething();
}
}
如果您调用onClick(..)
方法,则在调用之前永远不会停止doIt()
方法调用。因为每次都会创建new Handler
和new Runnable
个实例。这样,您丢失了属于处理程序和 runnable 实例的必要引用。
真实的方式:
public class FooActivity extends Activity {
Handler handler = new Handler();
Runnable runnable = new Runnable() {
@Override
public void run() {
doIt();
}
};
private void handleSomething(){
if(shouldIDoIt){
//doIt() works after 3 seconds.
handler.postDelayed(runnable, 3000);
} else {
handler.removeCallbacks(runnable);
}
}
public void onClick(View v){
handleSomething();
}
}
通过这种方式,您不会丢失实际引用,并且removeCallbacks(runnable)
能够成功运行。
关键句是'在Activity
或Fragment
使用的内容中将其定义为全局。。
答案 5 :(得分:1)
正如josh527
所说,handler.removeCallbacksAndMessages(null);
可以工作。
但是为什么呢?
如果您查看源代码,则可以更清楚地了解它。
可以从处理程序(MessageQueue)中删除回调/消息的方法有3种:
Handler.java(保留一些重载方法)
/**
* Remove any pending posts of Runnable <var>r</var> with Object
* <var>token</var> that are in the message queue. If <var>token</var> is null,
* all callbacks will be removed.
*/
public final void removeCallbacks(Runnable r, Object token)
{
mQueue.removeMessages(this, r, token);
}
/**
* Remove any pending posts of messages with code 'what' and whose obj is
* 'object' that are in the message queue. If <var>object</var> is null,
* all messages will be removed.
*/
public final void removeMessages(int what, Object object) {
mQueue.removeMessages(this, what, object);
}
/**
* Remove any pending posts of callbacks and sent messages whose
* <var>obj</var> is <var>token</var>. If <var>token</var> is null,
* all callbacks and messages will be removed.
*/
public final void removeCallbacksAndMessages(Object token) {
mQueue.removeCallbacksAndMessages(this, token);
}
MessageQueue.java可以完成实际工作:
void removeMessages(Handler h, int what, Object object) {
if (h == null) {
return;
}
synchronized (this) {
Message p = mMessages;
// Remove all messages at front.
while (p != null && p.target == h && p.what == what
&& (object == null || p.obj == object)) {
Message n = p.next;
mMessages = n;
p.recycleUnchecked();
p = n;
}
// Remove all messages after front.
while (p != null) {
Message n = p.next;
if (n != null) {
if (n.target == h && n.what == what
&& (object == null || n.obj == object)) {
Message nn = n.next;
n.recycleUnchecked();
p.next = nn;
continue;
}
}
p = n;
}
}
}
void removeMessages(Handler h, Runnable r, Object object) {
if (h == null || r == null) {
return;
}
synchronized (this) {
Message p = mMessages;
// Remove all messages at front.
while (p != null && p.target == h && p.callback == r
&& (object == null || p.obj == object)) {
Message n = p.next;
mMessages = n;
p.recycleUnchecked();
p = n;
}
// Remove all messages after front.
while (p != null) {
Message n = p.next;
if (n != null) {
if (n.target == h && n.callback == r
&& (object == null || n.obj == object)) {
Message nn = n.next;
n.recycleUnchecked();
p.next = nn;
continue;
}
}
p = n;
}
}
}
void removeCallbacksAndMessages(Handler h, Object object) {
if (h == null) {
return;
}
synchronized (this) {
Message p = mMessages;
// Remove all messages at front.
while (p != null && p.target == h
&& (object == null || p.obj == object)) {
Message n = p.next;
mMessages = n;
p.recycleUnchecked();
p = n;
}
// Remove all messages after front.
while (p != null) {
Message n = p.next;
if (n != null) {
if (n.target == h && (object == null || n.obj == object)) {
Message nn = n.next;
n.recycleUnchecked();
p.next = nn;
continue;
}
}
p = n;
}
}
}