先需要简单理解Handler Looper 不断的从 MessageQueue 中取出 Message 交给 Handler 来处理. 每个 Thread 对应一个 Looper, 每一个 Looper 只对应一个 MessageQueue, 每一个 MessageQueue 中有N个 Message, 每个 Message 只能定义一个 Handler 来处理。 ①一个线程中只能有一个Looper,只能有一个MessageQueue,可以有多个Handler,多个Messge; ②一个Looper只能维护唯一一个MessageQueue,可以接受多个Handler发来的消息; ③一个Message只能属于唯一一个Handler; ④同一个Handler只能处理自己发送给Looper的那些Message;
1: 消息循环机制的初始化
1.1: 主线程为什么会不断循环不退出
ActivityThread.java
main(){
Looper.prepareMainLooper();
Looper.loop();
}
Looper.java
public static void prepareMainLooper() {
prepare(false);
synchronized (Looper.class) {
if (sMainLooper != null) {
throw new IllegalStateException("The main Looper has already been prepared.");
}
sMainLooper = myLooper();
}
}
1.2: 创建 MessageQueue(消息队列)
Looper.java
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();
}
MessageQueue.java
MessageQueue(boolean quitAllowed) {
mQuitAllowed = quitAllowed;
mPtr = nativeInit();
}
这样一个消息队列就创建和初始化完成了。
2: 消息循环机制
2.1:Looper的循环机制
Looper.java
public static void loop() {
for (;;) {
Message msg = queue.next();
if (msg == null) {
return;
}
msg.target.dispatchMessage(msg);
}
}
2.2: Handler处理消息
Handler.java
public void dispatchMessage(@NonNull Message msg) {
if (msg.callback != null) {
handleCallback(msg);
} else {
if (mCallback != null) {
if (mCallback.handleMessage(msg)) {
return;
}
}
handleMessage(msg);
}
}
2.3: Message msg = queue.next();
Looper.java
public static void loop() {
for (;;) {
Message msg = queue.next();
if (msg == null) {
return;
}
}
}
MessageQueue.java
Message next() {
final long ptr = mPtr;
if (ptr == 0) {
return null;
}
int nextPollTimeoutMillis = 0;
for(;;){
nativePollOnce(ptr, nextPollTimeoutMillis);
msg = msg.next;
if(msg != null){
msg.next = null;
return msg;
}else{
nextPollTimeoutMillis = -1;
}
}
}
3: 消息池
我们从发送一个空消息来分析消息池。
Handler.java
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);
}
Message.java
public static Message obtain() {
synchronized (sPoolSync) {
if (sPool != null) {
Message m = sPool;
sPool = m.next;
m.next = null;
m.flags = 0;
sPoolSize--;
return m;
}
}
return new Message();
}
// 从这里可以看出先判断消息池里有没有消息,有就从消息池里面拿,没有就 new Message。所以处理完消息并不是直接被回收了,只有达到设置的最大值消息才能被回收。这样 // 可以重复利用消息。
4:消息入队
MessageQueue.java
boolean enqueueMessage(Message msg, long when) {
if (msg.target == null) {
throw new IllegalArgumentException("Message must have a target.");
}
Message p = mMessages;
if (p == null || when == 0 || when < p.when) {
msg.next = p;
mMessages = msg;
needWake = mBlocked;
}else{
}
if (needWake) {
nativeWake(mPtr);
}
消息队列退出时, 插入消息时, 移除同步屏障时 这三种情况会唤醒 Looper。
}
5: 异步消息即—同步屏障
Hnadler 消息分为同步消息和异步消息。我们一般用的就是同步消息。 同步和异步消息区别就是 Message 中的target不一样。同步消息 Message 没有 target,异步消息 Message 有 target。
5.1: 加入同步屏障
Handler.java
public Handler(boolean async);
public Handler(Callback callback, boolean async);
public Handler(Looper looper, Callback callback, boolean async);
创建Handler时 async 这个参数传 true, 这时 handler 发送的消息都是异步消息。
MessageQueue.java
public int postSyncBarrier() {
return postSyncBarrier(SystemClock.uptimeMillis());
}
private int postSyncBarrier(long when) {
synchronized (this) {
msg.next = p;
mMessages = msg;
}
return token;
}
5.2: 移除同步屏障
MessageQueue.java
public void removeSyncBarrier(int token) {
prev.next = p.next;
needWake = false;
if (needWake && !mQuitting) {
nativeWake(mPtr);
}
}
5.3: 异步消息的处理
Message next() {
for (;;) {
if (msg != null && msg.target == null) {
do {
prevMsg = msg;
msg = msg.next;
} while (msg != null && !msg.isAsynchronous());
}
..........
msg
..........
else {
mBlocked = false;
msg.next = null;
}
}
}
小结:发送异步消息前先添加一个同步屏障,在消息队列在取出消息时,遇到同步屏障就会优先处理异步消息,异步消息处理完后再处理同步消息。
|