android訊息機制—Looper
Looper在android的訊息機制充當訊息迴圈的角色,它不停的充MessageQueue中拿出訊息,並將訊息交給Hanlder處理,下面是他的常用方法解析。
Looper的建立
1. android主執行緒在建立的時候會主動建立一個Looper
ActivityThread是android的主執行緒,在該類的main函式中有如下部分程式碼
public static void main(String[] args) { ... //建立Looper Looper.prepareMainLooper(); ActivityThread thread = new ActivityThread(); thread.attach(false); ... } 複製程式碼
Looper.prepareMainLooper()方法的程式碼部分程式碼:
public static void prepareMainLooper() { //呼叫Looper的prepare()方法建立Looper prepare(false); ... } 複製程式碼
從上面的資訊我們可以知道,ActivityThread的main函式呼叫了Looper.prepareMainLooper函式,而在prepareMainLooper函式中有呼叫了Looper的prepare來建立Looper。那麼prepare函式是如何建立Looper呢?我們看下面第二中方式來分析。
2. 在子執行緒中直接使用Looper.prepare()方法建立
private static void prepare(boolean quitAllowed) { //一個執行緒中只能有一個Looper if (sThreadLocal.get() != null) { throw new RuntimeException("Only one Looper may be created per thread"); } //建立Looper sThreadLocal.set(new Looper(quitAllowed)); } 複製程式碼
線上程中我們可以呼叫Looper.prepare,這個函式中 sThreadLocal.set()中建立一個Looper,該方法不僅建立了Looper,其實也建立了MessageQueue,以及將Looper將當前執行緒和Looper關聯起來了。我們看一看Looper的構造就明白了
private Looper(boolean quitAllowed) { //建立訊息佇列 mQueue = new MessageQueue(quitAllowed); //獲取當前執行緒的引用 mThread = Thread.currentThread(); } 複製程式碼
Looper的的Loop方法
該方法主要是用來從訊息佇列裡面拿出訊息。我們可以看下面的部分原始碼
public static void loop() { ... final MessageQueue queue = me.mQueue; ... for (;;) { Message msg = queue.next(); // might block if (msg == null) { return; } ... try { //呼叫handler處理訊息 msg.target.dispatchMessage(msg); end = (slowDispatchThresholdMs == 0) ? 0 :SystemClock.uptimeMillis(); } finally { if (traceTag != 0) { Trace.traceEnd(traceTag); } } ... } } 複製程式碼
從上面的部分程式碼中loop()函式裡面有一個無限迴圈,這個迴圈就是不停的從MessageQueue中取訊息,並將取出訊息交給handler的dispatchMessage()來處理,只有當queue.next()取得Message為null的時候才跳出迴圈。
Looper其他常用方法
//獲取當前執行緒的Looper Looper looper = Looper.myLooper(); //獲取主線的Looper Looper mainLooper = Looper.getMainLooper(); //清除全部訊息 looper.quit(); //清除延遲訊息 looper.quitSafely(); 複製程式碼