Looper
Looper爲消息循環器, 不停的取出MessageQueue中的消息,並把獲取的消息分發下去。
是MessageQueue和Handle交互的橋樑。
- 提供prepare()方法
prepare方法中通過sThreadLocal(new Looper())
初始化了Looper, 並在Looper的構造方法中,new MessageQueue()
創建了messageQueue
- loop()
啓動循環遍歷消息,然後通過dispatchMessage()
把消息分發到Handle中。 - quite()
直接退出looper - quiteSafety()
做一個退出標記,等消息處理完後,再退出
如圖:
Looper對象只能創建一次。
子線程中創建Handler失敗,就是因爲子線程中沒有Looper對象導致的。
MessageQueue
MessageQueue是存儲的消息隊列,內部採用單鏈表的數據結構。
當消息來臨時,如果隊列爲空,就放入頭部中。
反之,按照創建時間進行插入鏈表中。
- enqueueMessage()
此方法就是存儲Message - next()
讀取消息
如圖:
Handler
handler用來發送和接受消息。
- Handler()
此時會獲取Looper、MessageQueue - 發送消息
發送消息分爲兩種方式。- sendMessage
- post
兩者最終調用的方法都是enqueueMessage
- 接受消息
接受消息也分爲兩個方式。- handleMessage
- handleCallback
發送的方式不同,接受的方式也就不同
如圖:
在主線程中,程序會通過Looper.PrepareMainLooper默認創建一個Looper,所以我們在使用時就不需要調用Looper.prepare方法,但是如果在子線程中使用Handle,必須調用Looper.prepare方法,進行創建Looper對象
Looper.PrepareMainLooper方法供系統調用,我們需要調用Looper.prepare方法
ps:子線程調用順序
ublic class LooperThread extends Thread {
public Handler mHandler;
@Override
public void run() {
//順序不可顛倒
Looper.prepare();
synchronized (this) {
mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
}
};
}
//順序不可顛倒
Looper.loop();
notifyAll();
}
Looper、Handler、MessageQueen關係
Handler通過post、sendMessage把消息發送給MessageQueen,MessageQueen通過enqueueMessage方法,把Message存儲到MessageQueen中,Looper在prepare()中,關聯了一個MessageQueen,Looper在loop()方法中,通過next()把消息取出來,如果爲空則阻塞Looper,否則通過dispatchMessage把消息分發到Handler中,Handle根據發送消息方式的不同,調用handleMessage、handleCallback不同的方法。
如圖: