在使用Handler时,当Activity销毁时,经常使用
mHandler.removeCallbacksAndMessages(null);虽然经常用,但大多数人都没深入了解一下。
这里简单记录一下,方便自己查询。
正文
这里主要涉及Handler 和MessageQueue。
Handler.java
\frameworks\base\core\java\android\os\Handler.java回到上面,我们关注removeCallbacksAndMessages()
/** * Remove any pending posts of callbacks and sent messages whose * obj is token. If token is null, * all callbacks and messages will be removed. */ public final void removeCallbacksAndMessages(@Nullable Object token) { mQueue.removeCallbacksAndMessages(this, disallowNullArgumentIfShared(token)); }
调用的是MessageQueue对象。
MessageQueue.java
\frameworks\base\core\java\android\os\MessageQueue.java//传入的object为null void removeCallbacksAndEqualMessages(Handler h, Object object) { if (h == null) { return; } synchronized (this) { Message p = mMessages; // Remove all messages at front. //因为object为null,如果target==h,那么就会进入循环中。 //如果target不为h的消息,那就跳过,进入下面 //【while 一】 while (p != null && p.target == h && (object == null || object.equals(p.obj))) { //进入这里的就是h的消息,因为我们要退出了 //因此要移除所有h的消息 Message n = p.next; mMessages = n; p.recycleUnchecked();//回收 p = n; } // Remove all messages after front. //p不为null,根据上面p肯定不是h的消息 //那就看p后面的消息是不是h的,然后一直遍历所有的。 //【while二】 while (p != null) { Message n = p.next; //下一个消息不为null时 if (n != null) { //判断是否是h的消息,如果是,那就需要移除。 if (n.target == h && (object == null || object.equals(n.obj))) { Message nn = n.next; n.recycleUnchecked();//回收 p.next = nn; continue; } } p = n; } } }
下面简单举例分析一下removeCallbacksAndEqualMessages()中的移除流程。
知识拓展
要知道Message、Looper、Handler、MessageQueue、以及Thread的对应关系。
| 关系 | 对应 |
|---|---|
| Thread | 持有 1 个 Looper |
| Looper | 持有 1 个 MessageQueue |
| Handler | 绑定 1 个 Looper(多个 Handler 可以共用同一个 Looper) |
| Message | 绑定 1 个 Handler(target) |
| MessageQueue | 持有 N 个 Message |
多个 Handler 可以共用同一个 Looper
//是h的消息下面有↑h messages → A → B → C → D → E → F ↑h ↑h ↑h
上面看做消息队列里面有A、B、C、D、E、F等消息。
假设消息A不是h分发的消息,那么就不满足代码中【while一】,p = message A,然后进入【while二】然后遍历后面的所有消息。
注意,后面的消息也不一定是h的,但是【while二】中做了全部的遍历,只有满足才会进入回收。
例子2
messages → A → B → C → D → E → F ↑h ↑h ↑h
当然,A和B都是h的消息,满足【while一】的条件,但是C不是,退出【while一】的循环,然后p=message C,然后进入【while二】的遍历循环。
参考文章
AI

