handle
handle:是傳送訊息,處理訊息
looper:是輪詢訊息
messageQueen:訊息佇列
程式的啟動有個主執行緒,也就是我們說的ui執行緒,ActivityThread執行緒有個main方法,在裡面呼叫了looper的啟動。
ActivityThread:
public static void main(String[] args) { ... Looper.prepareMainLooper(); ActivityThread thread = new ActivityThread(); thread.attach(false); if (sMainThreadHandler == null) { sMainThreadHandler = thread.getHandler(); } if (false) { Looper.myLooper().setMessageLogging(new LogPrinter(Log.DEBUG, "ActivityThread")); } // End of event ActivityThreadMain. Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); Looper.loop(); throw new RuntimeException("Main thread loop unexpectedly exited"); }
ui執行緒是系統給我們寫了looper的建立,但是我們自己寫的執行緒是沒有開啟訊息迴圈的,必須要自己呼叫Looper.prepare(), 然後呼叫Looper.loop();
class LooperThread extends Thread { public Handler mHandler; public void run() { Looper.prepare(); mHandler = new Handler() { public void handleMessage(Message msg) { // process incoming messages here } }; Looper.loop(); } }
Looper是如何與執行緒繫結的呢?
ThreadLocal<Looper>, Looper.prepare方法裡面,我們看到ThreadLocal.set方法將looper傳遞到Threadlocal裡面,這個裡面存在一個類似於map結構的model,將looper與thread作為<k,value>傳遞進去。
public void set(T value) { Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t); if (map != null) map.set(this, value); else createMap(t, value); }
handle,looper與messagequeue是如何聯絡的:
handle的構造方法裡面存在
public Handler(Callback callback, boolean async) { .... mLooper = Looper.myLooper(); //獲取到當前執行緒裡面的looper。 if (mLooper == null) { throw new RuntimeException( "Can't create handler inside thread that has not called Looper.prepare()"); } mQueue = mLooper.mQueue; //messagequeue在looper裡面new出來的,可以直接獲取 mCallback = callback; mAsynchronous = async; }
Looper裡面:
public static @Nullable Looper myLooper() { return sThreadLocal.get(); }