Handler、Looper、MessageQueue源碼解析——Handler



Handler


Handler 是Android中常用的異步通信的一個(gè)類(lèi),Android是一個(gè)消息驅(qū)動(dòng)的操作系統(tǒng),各種類(lèi)型的消息都是由Handler發(fā)出,再由Handler處理,那么對(duì)于Handler機(jī)制的理解就至關(guān)重要。

比如我們讓一個(gè)TextView延時(shí)3秒顯示"Hello World",我們會(huì)這樣寫(xiě):

Handler mHandler = new Handler();
mHandler.postDelayed(new Runnable() {
    @Override
    public void run() {
        mTextView.setText("Hello World");
    }
}, 3000);```

當(dāng)我們new 一個(gè)Handler時(shí),具體做了什么呢?從源碼中我們可以得到
答案:

Handler共有7種構(gòu)造方法:
```java
Handler() 

Handler(Callback callback)

Handler(Looper looper)

Handler(Looper looper, Callback callback)

/**@hide*/
Handler(boolean async)

/**@hide*/
Handler(Callback callback, boolean async)

/**@hide*/
Handler(Looper looper, Callback callback, boolean async)```

(注意@hide注解,表示這些API是不對(duì)外開(kāi)放的,但是在運(yùn)行的時(shí)候是可以使用這些API。雖然也是public的,但是不能直接調(diào)用,也無(wú)法通過(guò)反射獲取。所以我們?cè)谑褂肏andler時(shí)只能用前四個(gè)構(gòu)造方法。)

根據(jù)傳入?yún)?shù)的不同,最后都會(huì)調(diào)用這兩個(gè)構(gòu)造方法:

``` java
//沒(méi)有傳Looper
Handler(Callback callback, boolean async)
//傳了Looper
Handler(Looper looper, Callback callback, boolean async)```

至于Looper是什么,接下來(lái)再解釋。

看一下```Handler(Callback callback, boolean async)```這個(gè)構(gòu)造函數(shù):

``` java

    final Looper mLooper;
    final MessageQueue mQueue;
    final Callback mCallback;
    final boolean mAsynchronous;

    ...

    public Handler(Callback callback, boolean async) {
        //檢查Handler類(lèi)型,提示是否出現(xiàn)內(nèi)存泄漏warning
        if (FIND_POTENTIAL_LEAKS) {
            final Class<? extends Handler> klass = getClass();
            if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&
                    (klass.getModifiers() & Modifier.STATIC) == 0) {
                Log.w(TAG, "The following Handler class should be static or leaks might occur: " +
                    klass.getCanonicalName());
            }
        }
        
        // 得到Looper對(duì)像,稍后解釋
        mLooper = Looper.myLooper();
        if (mLooper == null) {
            throw new RuntimeException(
                "Can't create handler inside thread that has not called Looper.prepare()");
        }
        //獲得MessageQueue對(duì)象
        mQueue = mLooper.mQueue;
        //設(shè)置callback
        mCallback = callback;
        mAsynchronous = async;
    }```
首先通過(guò)```Looper.myLooper()```獲得Looper對(duì)象,再通過(guò)Looper對(duì)象獲取與Looper綁定的MessageQueue對(duì)象。

那么```Handler(Looper looper, Callback callback, boolean async)```這個(gè)構(gòu)造函數(shù)呢?

``` java
    public Handler(Looper looper, Callback callback, boolean async) {
        mLooper = looper;
        mQueue = looper.mQueue;
        mCallback = callback;
        mAsynchronous = async;
    }```
沒(méi)錯(cuò),區(qū)別就是Looper對(duì)象通過(guò)我們傳進(jìn)來(lái)的Looper對(duì)象來(lái)指定。

既然Handler是發(fā)送消息和處理消息的,那么Handler是怎么發(fā)送消息的呢?

官方為我們提供了這些方法:

```java
public final boolean post(Runnable r)
public final boolean postAtTime(Runnable r, long uptimeMillis)
public final boolean postDelayed(Runnable r, long delayMillis)
public final boolean postAtTime(Runnable r, Object token, long uptimeMillis)
public final boolean sendMessage(Message msg)
public final boolean sendEmptyMessage(int what)
public final boolean sendEmptyMessageDelayed(int what, long delayMillis)
public final boolean sendEmptyMessageAtTime(int what, long uptimeMillis)
public final boolean sendMessageDelayed(Message msg, long delayMillis)
public boolean sendMessageAtTime(Message msg, long uptimeMillis)```

看起來(lái)很多,其實(shí)最后都調(diào)用了一個(gè)方法```sendMessageAtTime(Message msg, long uptimeMillis)```。

什么?道理我都懂,post(Runnable r)是個(gè)什么東西?
其實(shí)post一系列方法最后調(diào)用的還是```sendMessageAtTime(Message msg, long uptimeMillis)```。

但是第一個(gè)參數(shù)傳進(jìn)去的是getPostMessage(r)
``` java
    private static Message getPostMessage(Runnable r) {
    //從Message pool里獲得一個(gè)Message或者新建一個(gè)Message對(duì)象
        Message m = Message.obtain();
        m.callback = r;
        return m;
    }

可以看出Runnable是Message的callback。Runnable callback是Message的一個(gè)成員變量,所以postXXX方法就是對(duì)Message的一個(gè)封裝。

那么我們重點(diǎn)看一下sendMessageAtTime方法。

    public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
    //從Looper中獲得的MessageQueue
        MessageQueue queue = mQueue;
        if (queue == null) {
            RuntimeException e = new RuntimeException(
                    this + " sendMessageAtTime() called with no mQueue");
            Log.w("Looper", e.getMessage(), e);
            return false;
        }s
        return enqueueMessage(queue, msg, uptimeMillis);
    }```

最后調(diào)用enqueueMessage方法:
``` java
    private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
        msg.target = this;
        if (mAsynchronous) {
            msg.setAsynchronous(true);
        }
        return queue.enqueueMessage(msg, uptimeMillis);
    }```

target是Message的一個(gè)Handler類(lèi)型的成員變量。所以sendMessageAtTime方法就是獲取MessageQueue,并為Message對(duì)象設(shè)置target屬性,然后把message插入到MessageQueue中。

Handler也提供了另外兩個(gè)方法,直接把消息插入到消息隊(duì)列第一個(gè):
  ```java
public final boolean postAtFrontOfQueue(Runnable r)
public final boolean sendMessageAtFrontOfQueue(Message msg)```

說(shuō)完了發(fā)送消息,接下來(lái)說(shuō)一下處理消息。

在Looper的 ``` loop()``` (開(kāi)啟消息循環(huán))方法有這樣一段代碼:
try {
    msg.target.dispatchMessage(msg);
} finally {
    if (traceTag != 0) {
        Trace.traceEnd(traceTag);
    }
}```

我們已經(jīng)知道m(xù)essage的target是一個(gè)Handler對(duì)象,消息的處理也就是調(diào)用了Handler的dispathMessage方法:

    public void dispatchMessage(Message msg) {
        if (msg.callback != null) {
            handleCallback(msg);
        } else {
            if (mCallback != null) {
                if (mCallback.handleMessage(msg)) {
                    return;
                }
            }
            handleMessage(msg);
        }
    }```
首先判斷message的callback是否為空,即我們通過(guò)postXXX方法發(fā)送的消息會(huì)給Message加上一個(gè)callback即Runnable,如果不為空調(diào)用handleCallback(msg):
``` java
    private static void handleCallback(Message message) {
        message.callback.run();
    }```
也就是調(diào)用Runnable的run()方法。

如果Message的Callback為空,接下來(lái)判斷mCallback是否為空,mCallback是什么呢,回到Handler的構(gòu)造方法,當(dāng)我們調(diào)用這兩個(gè)構(gòu)造方法```Handler(Callback callback) , Handler(Looper looper, Callback callback)```時(shí),我們會(huì)為Handler指定一個(gè)callback,當(dāng)Handler的callback不為空,會(huì)執(zhí)行callback的handleMessage方法,如果callback為空,則執(zhí)行Handler的handleMessage方法,這兩個(gè)方法的實(shí)現(xiàn)都為空,需要我們自己去實(shí)現(xiàn)。

Handler的源碼大部分就是這么多,其余的就是一些removeCallback之類(lèi)的方法。Handler的主要功能就是這些。接下來(lái)我們來(lái)學(xué)習(xí)其他兩個(gè)很重要的類(lèi)Looper。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀(guān)點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容