歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> Android基礎教程:一個activity中多個handler和消息的處理過程

Android基礎教程:一個activity中多個handler和消息的處理過程

日期:2017/3/1 11:08:13   编辑:Linux編程

Ø 能否有多個handler

handler的構造方法

public Handler() {

….

mLooper = Looper.myLooper();

mQueue = mLooper.mQueue;

mCallback = null;

}

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

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

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

1、 Handler發送消息的時候

public boolean sendMessageAtTime(Message msg, long uptimeMillis){

...

if (queue != null) {

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

sent = queue.enqueueMessage(msg, uptimeMillis);

}

...

}

2、而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();

}

}

}

3、這麼簡單的問題竟然糾結了好久,只能感歎菜鳥真可怕

既然看到這了,就稍微看下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)這兩種構造方法的時候才會被賦值

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

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

² 前邊兩個都為空的時候,才會調用Handler的handleMessage方法,如果沒有重寫,則調用系統默認的handleMessage,即什麼也不做

Copyright © Linux教程網 All Rights Reserved