以前一直以爲用handler的一個好處是能夠在其他thread發送消息到指定的thread 如UI thread中進行處理,
但用時不經意用到了handler的dispatchMessage(msg),才發現處理handlemessage時並沒有在UI thread中。
翻看dipatchMessage源碼才發現,
/**
* Handle system messages here.
*/
public void dispatchMessage(Message msg) {
if (msg.callback != null) {
handleCallback(msg);
} else {
if (mCallback != null) {
if (mCallback.handleMessage(msg)) {
return;
}
}
handleMessage(msg);////直接調用到了handler實現的handleMessage函數。 並沒有用MessageQuene來達到線程的轉換。
}
}
但sendMessage就不一樣了,
public final boolean sendMessage(Message msg)
{
return sendMessageDelayed(msg, 0);
}
public final boolean sendMessageDelayed(Message msg, long delayMillis)
{
if (delayMillis < 0) {
delayMillis = 0;
}
return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
}
public boolean sendMessageAtTime(Message msg, long uptimeMillis)
{
boolean sent = false;
MessageQueue queue = mQueue;
if (queue != null) {
msg.target = this;
sent = queue.enqueueMessage(msg, uptimeMillis);//通過MessageQuene發送到對應thread 的Looper進行處理
}
else {
RuntimeException e = new RuntimeException(
this + " sendMessageAtTime() called with no mQueue");
Log.w("Looper", e.getMessage(), e);
}
return sent;
}
所以以後用handler時記得最好還是用sendMessage 或者post系列函數,因爲post函數最終也會走到sendMessageAtTime()
在一個Activity中new handler時
handler = new Handler() {
@Override
public void handleMessage(Message msg) {
這時handler就已經 把當前的 UI thread信息attach到一起了。
public Handler() {
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());
}
}
mLooper = Looper.myLooper();//當前thread looper
if (mLooper == null) {
throw new RuntimeException(
"Can't create handler inside thread that has not called Looper.prepare()");
}
mQueue = mLooper.mQueue;//當前thread quene, sendmessage時也就是往這個quene裏發了。
mCallback = null;
}