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 flag
sPoolSize--;
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 block
if (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 变量实现循环复用