源碼地址
http://androidxref.com/7.1.2_r36/xref/frameworks/base/core/java/android/os/Handler.java
作用
Handler允許我們處理和發送與線程相關的消息隊列(MessageQueue)所關聯的Message或者Runnable對象。
每個Handler實例都和一個單獨的線程以及和該線程相關聯的MessageQueue相關聯。
所以,每當一個Handler實例創建時,它就被綁定到了一個線程,以及這個線程所關聯的MessageQueue上。
從這一點看,Handler會將Message和Runnable對象發送到MessageQueue中,並在他們從MessageQueue出棧時執行他們。
Handler的主要作用有兩點:
1、在未來某個時間調度message和runnable對象;
2、在其他線程(非當前線程)排隊執行一個動作;
handler主要有四種方式發送消息:
1、post 或 postDelayed:發送的是runnable對象
2、sendMessage 或 sendMessageDelayed:發送的是允許帶有一些數據的message對象;
這些消息對象將在Handler的實現對象中的handleMessage進行處理。
以上爲Handler類的官方說明的譯文(自己翻譯,如有誤,請指正)。
接下來將對源碼中的方法進行梳理:
成員變量
我們需要關注的成員變量爲:private static final boolean FIND_POTENTIAL_LEAKS = false;
這個成員變量默認爲false,如果設置爲true,就可以檢測出那些集成了handler類的,但是爲非靜態的匿名類、本地類或者成員類,這些類有可能導致內存泄露。
由此可見:我們在繼承或者實現handler類的時候,應該將其設置爲static。
處理消息有兩種方式,如下
/**
* 開發者在實現handler時,可以通過實現callback接口,來避免必須實現一個Handler子類。
*/
public interface Callback {
public boolean handleMessage(Message msg);
}
/**
* 子類必須實現該方法,用於處理消息對象
*/
public void handleMessage(Message msg) {
}
構造方法解析
Handler():默認構造,將handler和當前線程的Looper聯繫起來,如果當前線程不包含一個Looper,handler就不能收到消息,此時會報異常。
Handler(Callback callback):作用同Handler(),可以傳入message的處理回調對象,也可以爲null;
Handler(Looper looper):用指定的Looper來代替默認的Looper,不可爲null。
Handler(Looper looper, Callback callback):Looper對象傳入代替默認的null,不可爲null,callback可爲null;
Handler(boolean async):爲當前線程使用looper,並設置當前的handler是否是異步的。handler默認是同步的。異步消息的發出不需要
全局排序的中斷或者事件。異步事件不受MessageQueue引入的enqueueSyncBarrier(同步屏障)所限制。
Handler(Callback callback, boolean async):結合Handler(Callback callback)和Handler(boolean async)的釋義。
Handler(Looper looper, Callback callback, boolean async):結合上述幾個方法的釋義。
構造方法的主要作用是:爲當前handler設置looper值(獲取或者指定),並通過looper獲取messagequeue,以及設置事件處理回調,同步或者異步。
消息(Message)對象獲取方法解析
通過Message.obtain方法從全局消息池中返回一個new消息對象。比創建分配一個實例更高效。重新激活的消息會將它關聯的handler設置爲當前的
Handler實例。你也可以直接調用Message.obtain()方法獲取
public final Message obtainMessage() { return Message.obtain(this); }
what參數設置給Message.what的值
public final Message obtainMessage(int what) { return Message.obtain(this, what); }
what參數設置爲Message.what,obj設置爲Message.obj
public final Message obtainMessage(int what, Object obj) { return Message.obtain(this, what, obj); }
public final Message obtainMessage(int what, int arg1, int arg2) { return Message.obtain(this, what, arg1, arg2); }
public final Message obtainMessage(int what, int arg1, int arg2, Object obj) { return Message.obtain(this, what, arg1, arg2, obj); }
發送Runnable對象方法解析
Runnable對象都是通過post開頭的方法進行發送,runnable對象會通過getPostMessage方法將runnable對象,轉爲Message對象。
runnable對象就是Message對象中的回調,實現如下:
private static Message getPostMessage(Runnable r) { Message m = Message.obtain(); m.callback = r; return m; }
public final boolean post(Runnable r) { return sendMessageDelayed(getPostMessage(r), 0); }
public final boolean postAtTime(Runnable r, long uptimeMillis) { return sendMessageAtTime(getPostMessage(r), uptimeMillis); }
public final boolean postAtTime(Runnable r, Object token, long uptimeMillis) { return sendMessageAtTime(getPostMessage(r, token), uptimeMillis); }
public final boolean postDelayed(Runnable r, long delayMillis) { return sendMessageDelayed(getPostMessage(r), delayMillis); }
移除消息、移除回調、是否有消息、是否有回調等方法,都和當前handler綁定的messageQueue相關。
public final void removeMessages(int what) { mQueue.removeMessages(this, what, null); }
public final void removeCallbacksAndMessages(Object token) { mQueue.removeCallbacksAndMessages(this, token); }
public final boolean hasMessages(int what) { return mQueue.hasMessages(this, what, null); }
public final boolean hasMessages(int what, Object object) { return mQueue.hasMessages(this, what, object); }
public final boolean hasCallbacks(Runnable r) { return mQueue.hasMessages(this, r, null); }
以上就是Handler類的方法解析與說明。接下來還有幾點需要弄清楚:
1、什麼是MessageQueue
2、什麼是Looper
3、線程和MessageQueue的關係
4、線程和Looper的關係
5、Runnable和Message的關係