一個activity中多個handler和消息的處理過程

轉(zhuǎn)自:https://blog.csdn.net/cs_epo/article/details/69420

? 能否有多個handler

handler的構(gòu)造方法

public Handler() {

     ….

mLooper = Looper.myLooper();

mQueue = mLooper.mQueue;

mCallback = null;

}

因為幾乎主要的成員變量都是從Looper中拿出來的,最初以為一個線程中只能有一個handler。后來看構(gòu)造方法也沒有限制,嘗試的寫了下,發(fā)現(xiàn)的確可以實例化多個handler

后來又想,如果兩個handler都重寫了handleMessage方法,而handleMessage方法之后,消息會從消息隊列中移除。那么假設A發(fā)送了一個消息,想實現(xiàn)一些功能,但是B卻對這個消息進行了處理,那么A中的功能不是無法實現(xiàn)了嗎?

重新看了一下消息的分法機制,終于恍然大悟

1、 Handler發(fā)送消息的時候

public boolean sendMessageAtTime(Message msg, long uptimeMillis){

...

    **if** (queue !=**null**) {

        msg.target = **this**;// 發(fā)送消息的時候會把target設為當前的Handler

        sent = queue.enqueueMessage(msg, uptimeMillis);

    }

...

}

2、而Looper中的循環(huán)

public static final void loop() {

    Looper me = *myLooper*();

    MessageQueue queue = me.mQueue;

    **while** (**true**) {

    ...

        Message msg = queue.next();

    ...

    // 我汗啊… 竟然直接交給了target即發(fā)送這個消息的handler處理

       msg.target.dispatchMessage(msg);

       msg.recycle();

        }

    }

}

3、這么簡單的問題竟然糾結(jié)了好久,只能感嘆菜鳥真可怕

既然看到這了,就稍微看下dispatchMessage的邏輯吧

? dispatchMessage

|

public void dispatchMessage(Message msg) {

    **if** (msg.callback !=**null**) {

        handleCallback(msg);

    } **else** {

      **if** (mCallback !=**null**) {

            **if** (mCallback.handleMessage(msg)) {

                **return**;

            }

       }

        handleMessage(msg);

    }

}

|

2 -- 如果msg.callback不為空,則調(diào)用handleCallback(msg);

callback是一個Runnable的實例,那么什么時候不為空呢?

|- 當調(diào)用 message 的obtain靜態(tài)方法來實例化Message的時候,會對這個Runnable賦值

**public static** Message obtain(Handler h, Runnable callback) {

    Message m = *obtain*();

    m.target = h;

    m.callback = callback;

    **return** m;

}

|- 更常用的方式

當Handler.post(Runnable r)的時候

|

**public final boolean** post(Runnable r)

** return** sendMessageDelayed(getPostMessage(r), 0);

}

**private final** Message getPostMessage(Runnable r) {

    Message m = Message.*obtain*();

    m.callback = r;

    return m;

}

|

這時候,handler dispatch這個消息會直接調(diào)用Runnable中的run方法

這也是為什么重寫的handlerMessage不對這種形式發(fā)送的消息進行處理

2 如果mCallback不為空,則調(diào)用mCallback.handleMessage方法

而這個Callback默認情況下為空,只有當調(diào)用

public Handler(Callback callback)或者public Handler(Looper looper, Callback callback)這兩種構(gòu)造方法的時候才會被賦值,其實也就是要直接通過new hanlder ()構(gòu)造實例使用,而不是通過內(nèi)部類重寫handlerMessage 方式來處理的時侯采用的手段。

當然,一般使用handler處理消息都是為了與ui線程通信,而ui的looper是系統(tǒng)維護的,所以推薦第一種方式。 

當dispatch消息的時候,會直接調(diào)用callback.handleMessage()方法

2 前邊兩個都為空的時候,才會調(diào)用Handler的handleMessage方法,如果沒有重寫,則調(diào)用系統(tǒng)默認的handleMessage,即什么也不做

?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

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

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