Answers:
根据我的经验,这非常有效!
handler.removeCallbacksAndMessages(null);
在removeCallbacksAndMessages的文档中,它说...
删除obj为令牌的回调和已发送消息的所有未决帖子。如果token是
null
,则将删除所有回调和消息。
removeCallbacksAndMessages(null)
无法删除某些回调。当我想停止接收回调时,我会调用handler.removeCallbacksAndMessages(null)
并将我的处理程序设置为null,但是由于我仍然会收到回调,因此当我想与循环时会遇到NPE handler.postDelayed()
。
yourHandler.removeCallbacks(yourRunnable)
是最可靠的。今天仍在使用。
对于任何特定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
它,因为添加和删除项目的方法有包保护(只android.os包中的类可以给他们打电话)相关联的对象。您可能必须创建一个瘦子Handler
类来管理Runnable
s 的列表,这些列表在发布/执行时……或查看另一种在每个s之间传递消息的范式Activity
希望对您有所帮助!
如果没有Runnable引用,请在第一个回调上获取消息的obj,然后使用removeCallbacksAndMessages()删除所有相关的回调。
请注意,应该定义一个Handler
和一个Runnable
in类范围,以便一次创建它。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);
可以工作。
但为什么?
如果您查看源代码,则可以更清楚地了解它。可以从处理程序(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;
}
}
}