什么是Android Handler機制?
UI更新機制和消息處理機制。
角色和角色的生成
四個主要角色
- Message:消息壳贪,包含Handler。
- MessageQueue:消息隊列寝杖。
- Handler:包含MessageQueue违施,發(fā)送消息,處理消息瑟幕。
- Looper:包含MessageQueue磕蒲,遍歷MessageQueue,找到待處理的消息來處理只盹。
角色的生成
Lopper:Looper通過prepare()方法生成辣往,生成的時候創(chuàng)建MessageQueue,并且將Looper對象放到ThreadLocal(保存Thread相關數(shù)據(jù)的類)中殖卑,再次調用prepare()方法的時候會拋出運行時異常站削。
UI線程的Looper對象在線程創(chuàng)建的時候自動生成,并且調用Looper.loop()死循環(huán)遍歷MessageQueue
關鍵代碼如下:
// Looper類
private static void prepare(booleanquitAllowed) {
if(sThreadLocal.get() !=null) {
throw newRuntimeException("Only one Looper may be created per thread");
}
sThreadLocal.set(newLooper(quitAllowed));
}
private Looper(booleanquitAllowed) {
mQueue=newMessageQueue(quitAllowed);
mThread= Thread.currentThread();
}
Handler生成的時候會通過Looper.myLooper()去取ThreadLocal中的Looper孵稽,如果取不到會拋出運行時異常许起,如果取到了就將自己的MessageQueue和Looper的MessageQueue進行關聯(lián)。關鍵代碼如下:
// Handler類
public Handler(Callback callback, booleanasync) {
......
mLooper= Looper.myLooper();
if(mLooper==null) {
throw newRuntimeException(
"Can't create handler inside thread that has not called Looper.prepare()");
}
mQueue=mLooper.mQueue;
mCallback= callback;
mAsynchronous= async;
}
Handler消息發(fā)送和處理過程
消息發(fā)送
- 將Message加入Handler的MessageQueue
- 將Message的Handler和發(fā)送消息的Handler關聯(lián)(也就是Message對象持有發(fā)送它自己的Handler對象)
關鍵代碼如下:
// Handler類
public final boolean sendMessageAtFrontOfQueue(Message msg) {
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, 0);
}
private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
msg.target = this;
if (mAsynchronous) {
msg.setAsynchronous(true);
}
return queue.enqueueMessage(msg, uptimeMillis);
}
消息處理
前面提到菩鲜,UI線程啟動的時候就生成了該線程Looper對象园细,并且調用loop()方法死循環(huán)遍歷MessageQueue,所以消息處理就是當遍歷到某個Message的時候就調用Message關聯(lián)的Handler的handleMessage()來處理它接校。
Tip:
若Handler引用了Activity猛频,而Handler發(fā)送的消息在MessageQueue中一直未被處理,會導致Activity無法被回收。