【Android源碼閱讀】handler類

源碼地址

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的關係

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章