看下Android Looper源代碼,有助于理解Android系統消息循環流程、handler機制。Looper注釋為class used to run a message loop for a thread, 即用于為一個線程運行消息循環, 或者說循環處理一個線程的消息。 Looper源碼先看下這個類里的變量。
1、static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();
保存Looper對象,線程隔離,即每個線程最多只能有一個Looper對象。
2、private static Looper sMainLooper;
主線程的Looper對象
3、private static Observer sObserver;
觀察者,一般用不到, 可以調試用。當即將處理消息,消息處理完,消息處理有異常時,會調用該觀察者的相關方法。
4、final MessageQueue mQueue;
即消息隊列。每個looper循環處理該隊列中的消息。
5、final Thread mThread;
線程對象,該looper所屬線程,即該looper處理哪個線程的消息。
6、private boolean mInLoop;
標識是否已啟動消息循環
7、其他變量
private Printer mLogging; ?
private long mTraceTag;
private long mSlowDispatchThresholdMs;
private long mSlowDeliveryThresholdMs;
這些都是調試用,不用關注。
再下面看下Looper中的核心方法。
1、prepare方法
可見,prepare方法只能調用一次,用于生成Looper對象(Looper構造方法是私有的只能通過prepare方法生成Looper對象),并將其保存(關聯)到當前線程。還為該Looper生成一個消息隊列。傳的quitAllowed參數表示消息隊列是否可退出。
2、prepareMainLooper
用于生成主線程的Looper對象。應用開發用不到這個方法,用到主線程Looper直接獲取就行。該方法是應用啟動過程中調用的,如下:
3、getMainLooper
獲取主線程Looper對象。上面說了,主線程Looper對象早就生成好了。子線程Looper對象才需要調用prepare方法生成。
4、myLooper
獲取當前線程的Looper對象。為空就是沒調用prepare方法。
5、myQueue
當前線程(或者說Looper)關聯的消息隊列
6、isCurrentThread
判斷該Looper對象循環處理哪個線程的消息,是否為當前線程的。
7、quit
退出消息循環。只用于子線程。
8、getThread
獲取當前Looper處理的哪個線程的消息。獲取該線程對象
9、getQueue
獲取該looper循環的消息隊列
10、loop
為當前線程啟動消息循環,循環處理消息。截圖:
for語句里調用Message msg = queue.next(); // might block
這個方法從消息隊列中獲取消息。這里提示有可能阻塞當前線程。
中間有一些無關緊要的代碼,打印調用過程的,或者調試的代碼。略過。。。
然后,msg.target.dispatchMessage(msg);這一句代碼是分發并處理消息。target即該消息關聯的handler對象,此消息由該handler分發處理。
? ?ok. Looper源碼就這些, Looper注釋中介紹了子線程怎樣實現消息循環:
Ok. ?Handler、消息隊列源碼后續會另起一篇閱讀。