1.Handler
handler的主要功能是发送消息和处理消息。在源码中,主要有四类方法:构造方法,获取 Message 的方法,发送 Message 的方法,处理Message 的方法。
1)handler 的构造方法。
可以看出,一个 handler 只对应一个 looper ,而 looper 和 thread 是一对一的关系。
public Handler(Callback callback, boolean async) {if (FIND_POTENTIAL_LEAKS) {final Class<? extends Handler> klass = getClass();if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&(klass.getModifiers() & Modifier.STATIC) == 0) {Log.w(TAG, "The following Handler class should be static or leaks might occur: " +klass.getCanonicalName());}}mLooper = Looper.myLooper();if (mLooper == null) {throw new RuntimeException("Can't create handler inside thread that has not called Looper.prepare()");}mQueue = mLooper.mQueue;mCallback = callback;mAsynchronous = async;
}public Handler(Looper looper, Callback callback, boolean async) {mLooper = looper;mQueue = looper.mQueue;mCallback = callback;mAsynchronous = async;
}
2)获取 Message
这些获取 Message 的方法,实际上都是通过 Message 类获取的。见 Message 类分析。
public final Message obtainMessage(){return Message.obtain(this);}public final Message obtainMessage(int what){return Message.obtain(this, what);}public final Message obtainMessage(int what, Object obj){return Message.obtain(this, what, obj);}public final Message obtainMessage(int what, int arg1, int arg2){return Message.obtain(this, what, arg1, arg2);}public final Message obtainMessage(int what, int arg1, int arg2, Object obj){return Message.obtain(this, what, arg1, arg2, obj);}
3)发送消息的方法
这些方法最终都是通过 sendMessageAtTime 方法来发送消息的。
public final boolean post(Runnable r){return sendMessageDelayed(getPostMessage(r), 0);}public final boolean postAtTime(Runnable r, long uptimeMillis){return sendMessageAtTime(getPostMessage(r), uptimeMillis);}public final boolean postAtTime(Runnable r, Object token, long uptimeMillis){return sendMessageAtTime(getPostMessage(r, token), uptimeMillis);}public final boolean postDelayed(Runnable r, long delayMillis){return sendMessageDelayed(getPostMessage(r), delayMillis);}public final boolean sendMessage(Message msg){return sendMessageDelayed(msg, 0);}public final boolean sendEmptyMessage(int what){return sendEmptyMessageDelayed(what, 0);}public final boolean sendEmptyMessageDelayed(int what, long delayMillis) {Message msg = Message.obtain();msg.what = what;return sendMessageDelayed(msg, delayMillis);}public final boolean sendEmptyMessageAtTime(int what, long uptimeMillis) {Message msg = Message.obtain();msg.what = what;return sendMessageAtTime(msg, uptimeMillis);}public final boolean sendMessageDelayed(Message msg, long delayMillis){if (delayMillis < 0) {delayMillis = 0;}return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);}public boolean sendMessageAtTime(Message msg, long uptimeMillis) {MessageQueue queue = mQueue;if (queue == null) {RuntimeException e = new RuntimeException(this + " sendMessageAtTime() called with no mQueue");Log.w("Looper", e.getMessage(), e);return false;}return enqueueMessage(queue, msg, uptimeMillis);}private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {msg.target = this;if (mAsynchronous) {msg.setAsynchronous(true);}return queue.enqueueMessage(msg, uptimeMillis);}
4)处理消息的方法
通过 dispatchMessage 方法处理消息。首先,如果 Message 的 callback(runnable)不为空,让此 callback(runnable)来处理;其次,让 handler 的内部类 Callback 的实例来处理;最后,如果都不处理,就让 handler 默认的 handleMessage 方法来处理。我们在创建 handler 的实例时,重写的就是 handleMessage 方法。
public void dispatchMessage(Message msg) {if (msg.callback != null) {handleCallback(msg);} else {if (mCallback != null) {if (mCallback.handleMessage(msg)) {return;}}handleMessage(msg);}}private static void handleCallback(Message message) {message.callback.run();}public interface Callback {public boolean handleMessage(Message msg);}public void handleMessage(Message msg) {}
2.Message
handler 获取 Message 的方法实际上就是调用了 Message 自己的静态方法。使用 handler.post(runnable) 方法时,runnable 最终成为 Message 的 callabck 成员变量。
sPool 默认为空,使用 new Message() 创建第一个 Message 并且此 Message 在 recycleUnchecked() 方法中被回收利用时,将它指向 sPool。sPool 和 next 实现 Message 的循环利用。因此推荐在代码中使用 obtain 方法而不是 new 方法来获取 Message。
主要源码如下。
public int what;public int arg1; public int arg2;public Object obj;/*package*/ long when;/*package*/ Handler target;/*package*/ Runnable callback;/*package*/ Message next;private static final Object sPoolSync = new Object();private static Message sPool;private static int sPoolSize = 0;private static final int MAX_POOL_SIZE = 50;private static boolean gCheckRecycle = true;
void recycleUnchecked() {// Mark the message as in use while it remains in the recycled object pool.// Clear out all other details.flags = FLAG_IN_USE;what = 0;arg1 = 0;arg2 = 0;obj = null;replyTo = null;sendingUid = -1;when = 0;target = null;callback = null;data = null;synchronized (sPoolSync) {if (sPoolSize < MAX_POOL_SIZE) {next = sPool;sPool = this;sPoolSize++;}}}public static Message obtain() {synchronized (sPoolSync) {if (sPool != null) {Message m = sPool;sPool = m.next;m.next = null;m.flags = 0; // clear in-use flagsPoolSize--;return m;}}return new Message();}public static Message obtain(Handler h, Runnable callback) {Message m = obtain();m.target = h;m.callback = callback;return m;}public static Message obtain(Handler h, int what, int arg1, int arg2, Object obj) {Message m = obtain();m.target = h;m.what = what;m.arg1 = arg1;m.arg2 = arg2;m.obj = obj;return m;}
3.Looper
looper 的主要源码如下。可以看出一个线程对应一个 looper,一个 looper 对应一个 MessageQueue。
1)prepare 方法和静态 sThreadLocal 表明,所有线程的 looper 实例共享一个key -> sThreadLocal,把 looper 实例保存到自己对应 Thread的 ThreadLocalMap 中。
2)在调用 prepare 方法之前,thread 的 looper 为空。
3)在 loop() 方法中,for(;;) 无限循环获取 Message msg = queue.next(),只有在获取的 msg == null 的时候才会退出 for 循环,结束 loop() 方法。queue.next() 对于 MessageQueue 是个阻塞式方法。
static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();
private static Looper sMainLooper; // guarded by Looper.class
final MessageQueue mQueue;
final Thread mThread;private Looper(boolean quitAllowed) {mQueue = new MessageQueue(quitAllowed);mThread = Thread.currentThread();}private static void prepare(boolean quitAllowed) {if (sThreadLocal.get() != null) {throw new RuntimeException("Only one Looper may be created per thread");}sThreadLocal.set(new Looper(quitAllowed));}public static void prepareMainLooper() {prepare(false);synchronized (Looper.class) {if (sMainLooper != null) {throw new IllegalStateException("The main Looper has already been prepared.");}sMainLooper = myLooper();}}public static @Nullable Looper myLooper() {return sThreadLocal.get();}public static Looper getMainLooper() {synchronized (Looper.class) {return sMainLooper;}}public static @NonNull MessageQueue myQueue() {return myLooper().mQueue;}public static void loop() {final Looper me = myLooper();final MessageQueue queue = me.mQueue;...for (;;) {Message msg = queue.next(); // might blockif (msg == null) {// No message indicates that the message queue is quitting.return;}...msg.target.dispatchMessage(msg);...msg.recycleUnchecked();}}
总结一下:
Handler:
在构造方法中通过 mLooper = Looper.myLooper() 和 mQueue = mLooper.mQueue 获取 looper 和 looper 的消息队列
通过 Message.obtain() 获取 message
通过 sendMessageAtTime 最终使用 queue.enqueueMessage(msg, uptimeMillis) 把消息加入消息队列
通过 msg.callback.run 和 handler.callback.handleMessage 和 handler.handleMessage 处理消息
Message:
通过 sPool 和 next 两个变量实现循环利用
Looper:
在构造方法中获取 mQueue = new MessageQueue(quitAllowed) 和 mThread = Thread.currentThread();
通过 prepare 方法和 ThreadLocal 来把 looper 实例保存到实例所在线程的 ThreadLocalMap 中
通过 loop 方法和 MessageQueue 阻塞式的获取 Message
再浓缩总结:
1.Thread 有 ThreadLocalMap threadLocals 变量来保存相关 value
2.ThreadLocal 中通过 createMap 方法初始化 ThreadLocalMap 并把它赋值为 Thread 的 threadLocals
3.Looper 有静态属性 static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>(),在调用 prepare 方法时以sThreadLocal 为 key 保存 looper 到 ThreadLocalMap;
以 mQueue = new MessageQueue(quitAllowed) 来初始化消息队列;
以 loop 方法配合 MessageQueue 来不断获取 Message。
4.handler 在构造方法中以 mLooper = Looper.myLooper() 持有 looper
5.Message类保存了相关属性,以 obtain 方法和 sPool、next 变量实现循环复用