Handler是面试一定会问得机制,每次都能够打上来,但是答的很浅,只是说了大概的一个工作机制,画了个图从源码的角度加深自己的理解吧。首先上图
上面是大概的一个工作机制,从源码的角度来说其实没有太多重要的地方,主要就关注这么几个类
Message:承载着消息的对象。
MessageQueue:存放消息的队列
Handler:负责发送消息和接收消息的对象
Looper:消息循环机制
通常都会使用消息池机制,如下可以获得一个Message对象
Message.obtain(this)obtain()
message.sendToTarget();
Message message = handler.obtainMessage();
//从源码的角度来说其实在里面做了那么一件事情,它会把当前的那个handler传进来,到之后后面的message可以直接调用
//message.sendToTarget();
public static Message obtain(Handler h) {
Message m = obtain();
m.target = h;
return m;
}
在obtain这个方法里面又干了这么一件事情
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();
}
//看看就能够知道了,第一次创建的时候是没有消息池的,直接new 了一个对象出去,在后面会把该消息放入消息池
//这里完成了消息的初始化,当执行完自己的逻辑之后调用message.sendToTarget();通过保存在message内部的
//handler发送消息到消息池里面
boolean enqueueMessage(Message msg, long when) {
if (msg.target == null) {
throw new IllegalArgumentException("Message must have a target.");
}
if (msg.isInUse()) {
throw new IllegalStateException(msg + " This message is already in use.");
}
synchronized (this) {
if (mQuitting) {
IllegalStateException e = new IllegalStateException(
msg.target + " sending message to a Handler on a dead thread");
Log.w("MessageQueue", e.getMessage(), e);
//在这里实现了消息的回收,实际上就是把消息放回消息池
msg.recycle();
return false;
}
msg.markInUse();
msg.when = when;
Message p = mMessages;
boolean needWake;
if (p == null || when == 0 || when < p.when) {
// New head, wake up the event queue if blocked.
msg.next = p;
mMessages = msg;
needWake = mBlocked;
} else {
// Inserted within the middle of the queue. Usually we don't have to wake
// up the event queue unless there is a barrier at the head of the queue
// and the message is the earliest asynchronous message in the queue.
needWake = mBlocked && p.target == null && msg.isAsynchronous();
Message prev;
for (;;) {
prev = p;
p = p.next;
if (p == null || when < p.when) {
break;
}
if (needWake && p.isAsynchronous()) {
needWake = false;
}
}
msg.next = p; // invariant: p == prev.next
prev.next = msg;
}
// We can assume mPtr != 0 because mQuitting is false.
if (needWake) {
nativeWake(mPtr);
}
}
return true;
}
以上就是对handler的理解