以前一直以为用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;
}