Handler主要借助内部的三个类完成线程间的通信:
Looper,MessageQueue,Message
在android中:
- Handler创建:
//出自Handler
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 " + Thread.currentThread()
+ " that has not called Looper.prepare()");
}
mQueue = mLooper.mQueue;
mCallback = callback;
mAsynchronous = async;
}
//=================================出自Looper============================
public static @Nullable Looper myLooper() {
return sThreadLocal.get();
}
public static void prepare() {
prepare(true);
}
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));
}
private Looper(boolean quitAllowed) {
mQueue = new MessageQueue(quitAllowed);
mThread = Thread.currentThread();
}
非UI线程创建hander对象需要提前调用Looper.prepare();
创建完对象之后需要调用Looper.loop();(如果不调用的话handler将不能接收到消息)
(注:UI线程不需要手动调用的原因是在初始化的时候已经调用了)
- 消息的发送:
//代码出自Handler
private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
msg.target = this;
if (mAsynchronous) {
msg.setAsynchronous(true);
}
return queue.enqueueMessage(msg, uptimeMillis);
}
Handler的消息的发送是sendMessage最终调用的是MessageQueue的enqueueMessage()将消息压入MessageQueue中
- 消息的接收:
/**
* Run the message queue in this thread. Be sure to call
* {@link #quit()} to end the loop.
*/
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;
}
...
try {
//这里条用了handler的dispatchMessage方法
msg.target.dispatchMessage(msg);
dispatchEnd = needEndTime ? SystemClock.uptimeMillis() : 0;
} finally {
if (traceTag != 0) {
Trace.traceEnd(traceTag);
}
}
...
msg.recycleUnchecked();
}
}
Handler的消息是通过Looper.loop()方法(里面有个死循环) 不停的检测MessageQueue中是否有新的Message消息,如果有就调用Message对象保存的handler的dispatchMessage(msg)方法,dispatchMessage()方法最终会调用handleMessage(msg)方法.
- ps:
其中,Looper保存在线程的本地变量threadLocal中,Looper保存有当前线程和MessageQueue,通过Lopper.loop()方法循环的从MessageQueue中读取消息,一旦发现MessageQueue中有新的Message消息,就会调用target(就是当前线程的handler)的dispatchMessage方法分发消息