我们知道调用handler.removeCallbacksAndMessages(null);可以清空当前handler的所有回调和所有消息。想当然的认为handler.removeCallbacks(null)可以清空所有回调,实则不然。本文旨在探明其原因。
首先,打开Handler.java,removeCallbacksAndMessages方法如下:
/**
* 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);
}
可以看到,注释中有提到参数为null时会移除所有回调和message,再看removeCallbacks方法,注释中并没有提到参数为null时会移除所有回调。
/**
* Remove any pending posts of Runnable r that are in the message queue.
*/
public final void removeCallbacks(Runnable r)
{
mQueue.removeMessages(this, r, null);
}
如果还不确信的话,我们可以继续向下探究。上文可以看到无论是在removeCallbacksAndMessages方法还是removeCallbacks方法中都继续调用了mQueue对象中的removeCallbacksAndMessages和removeMessages方法,mQueue对象是MessageQueue类的实例,打开MessageQueue.java文件找到这两个方法。首先是removeCallbacksAndMessages:
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;
}
}
}
从该方法可以看出,当传入的object对象为null时,会循环回收掉所有message。在看removeMessages方法,当传入的Runnable为null时,会直接退出,该方法如下:
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;
}
}
}
所以handler.removeCallbacks(null)不会移除任何回调。
网友评论