重點(diǎn)類 : Handler诡必、Looper喷屋、MessageQueue舟铜、Message
1.Looper 的作用是將 Message 對(duì)象從 MessageQueue 中取出來辜伟,并將其交給 Handler#dispatchMessage(Message) 方法
2.Handler 的作用是將 Message 對(duì)象發(fā)送到 MessageQueue 中去菊霜,同時(shí)將自己的引用賦值給 Message#target坚冀。
3.MessageQueue 的作用負(fù)責(zé)插入和取出 Message
主線程一旦存在就創(chuàng)建了Looper,而Looper內(nèi)部又創(chuàng)建了MessageQueue鉴逞,所以在創(chuàng)建Handler的時(shí)候傳入了一個(gè)Looper對(duì)象记某,一般我們都是獲取Looper.getMainLooper(),這時(shí)候三者就關(guān)聯(lián)了起來构捡。使用Handler發(fā)送message其實(shí)就是往Looper對(duì)象的MessageQueue變量發(fā)送(起到存儲(chǔ)的作用)液南,而Looper內(nèi)部一直在輪詢(死循環(huán)阻塞)獲取MessageQueue的消息,一旦獲取到新消息則回調(diào)Handler的CallBack接口勾徽。
第一點(diǎn)解析
// 獲取Message用于存放信息
Message message = mHandler.obtainMessage();
=================源碼=====================
// 獲取一個(gè)Message
public final Message obtainMessage()
{
return Message.obtain(this);
}
// 將Handler引用賦值給Message對(duì)象的target字段
public static Message obtain(Handler h) {
Message m = obtain();
m.target = h;
return m;
}
MessageQueue 中的 Message 是有序的嗎滑凉?排序的依據(jù)是什么
是有序的。Queue 都是有序的(先進(jìn)先出)喘帚,Set 才是無序的畅姊,排序的依據(jù)是 Message#when 字段,表示一個(gè)相對(duì)時(shí)間吹由,該值是由 MessageQueue#enqueueMessage(Message, Long 時(shí)間) 方法設(shè)置的若未。
message.sendToTarget();
==================源碼==================
// 內(nèi)部是handler引用調(diào)用自身的方法
public void sendToTarget() {
target.sendMessage(this);
}
public final boolean sendMessage(Message msg)
{
return sendMessageDelayed(msg, 0);
}
····
····
····
最終調(diào)用MessageQueue#enqueueMessage(Message msg, long uptimeMillis)
handler處理事件源碼分析
public void dispatchMessage(Message msg) {
// 每個(gè)Message的callback 都是Runnable接口,分開設(shè)置處理
if (msg.callback != null) {
handleCallback(msg);
} else {
// 總處理倾鲫,mCallback 是構(gòu)造函數(shù)傳入的
if (mCallback != null) {
if (mCallback.handleMessage(msg)) {
return;
}
}
// 空實(shí)現(xiàn)粗合,上面mCallback ==null或者返回false都會(huì)執(zhí)行
handleMessage(msg);
}
}
如何判斷當(dāng)前線程是不是主線程
// 1
Looper.myLooper() == Looper.getMainLooper()
// 2
Looper.getMainLooper().getThread() == Thread.currentThread()
// 3 是上面2的簡化
Looper.getMainLooper().isCurrentThread()