handler是和線程MessageQueue隊列關聯發送和處理Message和Runnable的對象。html
1.發送Runnable方法以下:android
2.發送Message方法以下:數組
要注意的是handler發送Runnable對象方法其實是調用SendMessage方法。
直接查看源碼,Runnable做爲入參到getPostMessage轉換成Message對象,Runnable賦值給Message的callback,callback何用等會再講。安全
public final boolean post(Runnable r) { return sendMessageDelayed(getPostMessage(r), 0); } private static Message getPostMessage(Runnable r) { Message m = Message.obtain(); m.callback = r; return m; }
3.dispatchMessageless
Handler的handleMessage是經過dispatchMessage調用的,因此先講它。handler接收Message一共經過三種方式。異步
public void dispatchMessage(Message msg) { if (msg.callback != null) { handleCallback(msg); } else { if (mCallback != null) { if (mCallback.handleMessage(msg)) { return; } } handleMessage(msg); } }
private static void handleCallback(Message message) { message.callback.run(); }
public interface Callback { public boolean handleMessage(Message msg); }
/** * Subclasses must implement this to receive messages. */ public void handleMessage(Message msg) { }
4.接收Messageasync
因此沒有接收Runnable方法,也就知道爲何要把發送的Runnable轉成Message了。ide
5.注意!!函數
在子線程中建立Handler必需它的mLooper不能爲空。這點應該都比較清楚,Handler的構造函數中對mLooper是否爲空作了判斷,若爲空則拋出一個異常。因此在子線程中建立Handler以前先調用Looper.prepare()建立Looper以及實例化Looper的MessageQueue和Thread。oop
Looper是用於在Thread中運行消息隊列的類。Thread默認不關聯Looper。
1.prepare
在線程中調用prepare方法運行loop。
sThreadLocal.get()獲取Looper,若爲空則去new Looper()。
public static void prepare() { prepare(true); } private static void prepare(boolean quitAllowed) { if (sThreadLocal.get() != null) { throw new RuntimeException("Only one Looper may be created per thread"); } sThreadLocal.set(new Looper(quitAllowed)); }
2.loop
讓Looper進入循環處理MessageQueue中的Meessage。loop方法很長裏面主要有for(;;)作線程阻塞不斷從queue中拿Message分發給Hanlder去處理。具體在msg.target.dispatchMessage(msg)。msg.target對象就Hanlder。看這
for (;;) { Message msg = queue.next(); // might block if (msg == null) { // No message indicates that the message queue is quitting. return; } ...省略部分代碼 final long slowDispatchThresholdMs = me.mSlowDispatchThresholdMs; final long traceTag = me.mTraceTag; if (traceTag != 0 && Trace.isTagEnabled(traceTag)) { Trace.traceBegin(traceTag, msg.target.getTraceName(msg)); } final long start = (slowDispatchThresholdMs == 0) ? 0 : SystemClock.uptimeMillis(); final long end; try { msg.target.dispatchMessage(msg); end = (slowDispatchThresholdMs == 0) ? 0 : SystemClock.uptimeMillis(); } finally { if (traceTag != 0) { Trace.traceEnd(traceTag); } } ...省略部分代碼 msg.recycleUnchecked(); }
3.quit
Looper調用loop方法進入死循環,那如何讓Looper中止輪詢MessageQueue呢。Looper提供quit和quitSafely兩個方法退出Looper。
quit是非安全的,由於在Looer結束以前可能會存在一些Message還存在MessageQueue中不能被分發。*
Using this method may be unsafe because some messages may not be delivered before the looper terminates. Consider using {@link #quitSafely} instead to ensure that all pending work is completed in an orderly manner.
quit不安全,因此咱們使用quitSafely。保證MessageQueue中的Message被及時分發出去。然而延時的Message則不能在quit後分發出去。
Looper的退出都是調用了MessageQueue的quit。
public void quit() { mQueue.quit(false); } public void quitSafely() { mQueue.quit(true); }
如今要講的是MessageQueue。開始以前先把Looper調用quit先講了。MessageQueue的quit只要說safe控制的removeAllFutureMessagesLocked和removeAllMessagesLocked。
1.quit
void quit(boolean safe) { if (!mQuitAllowed) { throw new IllegalStateException("Main thread not allowed to quit."); } synchronized (this) { if (mQuitting) { return; } mQuitting = true; if (safe) { removeAllFutureMessagesLocked(); } else { removeAllMessagesLocked(); } // We can assume mPtr != 0 because mQuitting was previously false. nativeWake(mPtr); } }
private void removeAllMessagesLocked() { Message p = mMessages; while (p != null) { Message n = p.next; p.recycleUnchecked(); p = n; } mMessages = null; }
Ps: 因此handler發送Message或者Runnable的延時時間在這裏起了做用,根據傳入的延時時間作列表排序。
private void removeAllFutureMessagesLocked() { final long now = SystemClock.uptimeMillis(); Message p = mMessages; if (p != null) { if (p.when > now) { removeAllMessagesLocked(); } else { Message n; for (;;) { n = p.next; if (n == null) { return; } if (n.when > now) { break; } p = n; } p.next = null; do { p = n; n = p.next; p.recycleUnchecked(); } while (n != null); } } }
2.enqueueMessage
前面Handler講過發送Message,最終都會去執行queue的enqueueMessage方法。
private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) { msg.target = this; if (mAsynchronous) { msg.setAsynchronous(true); } return queue.enqueueMessage(msg, uptimeMillis); }
MessageQueue排列Message並非以數組形式,MessageQueue只持有當前的mMessages。新加入到隊列的Message會根據它的when判斷它在隊列的位置。還能夠看到若Thread已經dead,則拋出非法異常並把發送的Message回收。
boolean enqueueMessage(Message msg, long when) { if (msg.target == null) { throw new IllegalArgumentException("Message must have a target."); } if (msg.isInUse()) { throw new IllegalStateException(msg + " This message is already in use."); } synchronized (this) { if (mQuitting) { IllegalStateException e = new IllegalStateException( msg.target + " sending message to a Handler on a dead thread"); Log.w(TAG, e.getMessage(), e); msg.recycle(); return false; } msg.markInUse(); msg.when = when; Message p = mMessages; boolean needWake; if (p == null || when == 0 || when < p.when) { // New head, wake up the event queue if blocked. msg.next = p; mMessages = msg; needWake = mBlocked; } else { // Inserted within the middle of the queue. Usually we don't have to wake // up the event queue unless there is a barrier at the head of the queue // and the message is the earliest asynchronous message in the queue. needWake = mBlocked && p.target == null && msg.isAsynchronous(); Message prev; for (;;) { prev = p; p = p.next; if (p == null || when < p.when) { break; } if (needWake && p.isAsynchronous()) { needWake = false; } } msg.next = p; // invariant: p == prev.next prev.next = msg; } // We can assume mPtr != 0 because mQuitting is false. if (needWake) { nativeWake(mPtr); } } return true; }
<span id = "Message"></span>
最後就是Message了。Message主要成員參數有:long when、Bundle data、Handler target、Runnable callback、Message next。能夠看到Message沒有前驅只有一個後繼Message。因此MessageQueue只存當前mMessages也能找到下一個Message。
1.Runnable
Message有成員參數Runnable。還記得Handler的Post的是Runnable而後轉換成Message嗎,原來入參的Runnable到這裏來了。看這裏若Message的Runnable不爲空,Handler的dispathMessage但是會走這邊的。至關於Handler是Post方法,最後接收的時候是執行Runnable的run方法。
其實講這麼多就是爲了摸清楚Handler、Looper、MessageQueue以及Message。整個過程下來理清了Handler做爲Message的接收和發送者,將Message插入MessageQueue中。Looper則是做爲一個搬運者不停地從MessageQueue中拿取Mssage而後丟給Handler。那麼Handler做爲Message接收和發送者爲什麼畫蛇添足經過又是Queue又是Looper繞一圈呢?其實其中也有Thread的參與。因爲主題主要是Handler機制,因此Thread放在下次有時間單獨講。Handler就是解決進程間通訊問題以及異步處理事件,建立子線程作異步操做,把但願返回的內容返回到主線程達到不阻塞UI線程的目的。
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(); } }
拿了一張比較好理解的Handler機制運行的圖片來作結束。圖片來源已經在本文最後附上連接