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

 
Ø  可否有多個handler
handler的構造方法oop

public Handler() {post

         ….ui

mLooper = Looper.myLooper();this

mQueue = mLooper.mQueue;spa

mCallback = null;.net

線程

}blog

    由於幾乎主要的成員變量都是從Looper中拿出來的,最初覺得一個線程中只能有一個handler。後來看構造方法也沒有限制,嘗試的寫了下,發現的確能夠實例化多個handler隊列

    後來又想,若是兩個handler都重寫了handleMessage方法,而handleMessage方法以後,消息會從消息隊列中移除。那麼假設A發送了一個消息,想實現一些功能,可是B卻對這個消息進行了處理,那麼A中的功能不是沒法實現了嗎?get

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

一、 Handler發送消息的時候

public boolean sendMessageAtTime(Message msg, long uptimeMillis){

...

        if (queue !=null) {

            msg.target = this;// 發送消息的時候會把target設爲當前的Handler

            sent = queue.enqueueMessage(msg, uptimeMillis);

        }

...

}

二、而Looper中的循環

public static final void loop() {

        Looper me = myLooper();

        MessageQueue queue = me.mQueue;

        while (true) {

        ...

            Message msg = queue.next();

        ...

        // 我汗啊… 居然直接交給了target即發送這個消息的handler處理

           msg.target.dispatchMessage(msg);

           msg.recycle();

            }

        }

}

三、這麼簡單的問題居然糾結了很久,只能感嘆菜鳥真可怕

 

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

Ø  dispatchMessage
 

public void dispatchMessage(Message msg) {

        if (msg.callback !=null) {

            handleCallback(msg);

        } else {

          if (mCallback !=null) {

                if (mCallback.handleMessage(msg)) {

                    return;

                }

           }

            handleMessage(msg);

        }

}

²  --  若是msg.callback不爲空,則調用handleCallback(msg);

callback是一個Runnable的實例,那麼何時不爲空呢?

|-  當調用 message 的obtain靜態方法來實例化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這個消息會直接調用Runnable中的run方法

這也是爲何重寫的handlerMessage不對這種形式發送的消息進行處理

 

²  若是mCallback不爲空,則調用mCallback.handleMessage方法

而這個Callback默認狀況下爲空,只有當調用

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

    固然,通常使用handler處理消息都是爲了與ui線程通訊,而ui的looper是系統維護的,因此推薦第一種方式。 

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

 

²  前邊兩個都爲空的時候,纔會調用Handler的handleMessage方法,若是沒有重寫,則調用系統默認的handleMessage,即什麼也不作 ———————————————— 版權聲明:本文爲CSDN博主「boliu」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處連接及本聲明。 原文連接:https://blog.csdn.net/cs_epo/article/details/6942057

相關文章
相關標籤/搜索