我的子 Activity 有一个Handler,它由主Activity调用。这个 Handler 被postDelay
一些 Runnables 的子类使用,我无法管理它们。现在,在这种情况onStop
下,我需要在完成 Activity 之前删除它们(我以某种方式调用finish()
了 ,但它仍然一次又一次地调用)。无论如何要从处理程序中删除所有回调?
6 回答
根据我的经验,这很有效!
handler.removeCallbacksAndMessages(null);
在 removeCallbacksAndMessages 的文档中,它说...
删除所有待处理的回调和发送的消息,其 obj 是令牌。如果 token 是
null
,所有回调和消息都将被删除。
对于任何特定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
a Handler
,即使您请求MessageQueue
与其关联的对象也是如此,因为添加和删除项目的方法是包保护的(只有 android.os 包中的类可以调用它们)。您可能必须创建一个瘦子Handler
类来管理Runnable
发布/执行的 s 列表......或者查看另一种范式以在每个 s 之间传递消息Activity
希望有帮助!
如果您没有 Runnable 引用,则在第一个回调中,获取消息的 obj,并使用removeCallbacksAndMessages()删除所有相关回调。
定义一个新的处理程序并运行:
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);
请注意,应该在类范围内定义 aHandler
和 a 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
实例化。通过这种方式,您丢失了属于处理程序和可运行实例的必要引用。
正确方法:
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
” 。
如前所述josh527
,handler.removeCallbacksAndMessages(null);
可以工作。
但为什么?
如果你看一下源代码,你可以更清楚地理解它。有 3 种方法可以从处理程序(消息队列)中删除回调/消息:
- 通过回调(和令牌)删除
- 通过 message.what (和令牌)删除
- 令牌删除
Handler.java(留一些重载方法)</p>
/**
* 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;
}
}
}