能否有多個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方法之后,,消息會從消息隊列中移除,。那么假設(shè)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設(shè)為當(dāng)前的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的實例,那么什么時候不為空呢,?
|- 當(dāng)調(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;
}
|- 更常用的方式
當(dāng)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默認(rèn)情況下為空,,只有當(dāng)調(diào)用
public Handler(Callback callback)或者public Handler(Looper looper,
Callback callback)這兩種構(gòu)造方法的時候才會被賦值
當(dāng)然,一般使用handler處理消息都是為了與ui線程通信,,而ui的looper是系統(tǒng)維護的,,所以推薦第一種方式,。
當(dāng)dispatch消息的時候,會直接調(diào)用callback.handleMessage()方法
2
前邊兩個都為空的時候,,才會調(diào)用Handler的handleMessage方法,,如果沒有重寫,則調(diào)用系統(tǒng)默認(rèn)的handleMessage,,即什么也不做