Handler的两个主要用途:
(1) to schedule messages and
runnables to be executed as some point in the future;
(2) to enqueue an action to be performed on a different thread than your own.
Handler和创建它的线程绑定在一起,每个线程最多只有一个Looper对象,每个Looper只有一个MessageQueue。
当你创建一个Handler实例时,该实例就和创建它的线程、消息队列绑定。
Handler传递Messages给MessageQueue,并且在Looper从消息队列中取出时处理(通过handleMessage(Message msg)方法)。
Handler发送信息通过以下方法完成:
1.post,
2.postAtTime(Runnable, long),
3.postDelayed,
4.sendEmptyMessage,
5.sendMessage,
6.sendMessageAtTime,
7.sendMessageDelayed。
sendMessage(Message msg)方法和post(Runnable r)通过查看源码发现,最后调用的都是同一个方法。
public final boolean sendMessage(Message msg)
{
return sendMessageDelayed(msg, 0);
}
public final boolean post(Runnable r)
{
return sendMessageDelayed(getPostMessage(r), 0);
}
最后到调用了sendMessageDelayed()方法。
看一下getPostMessage(Runnable r),将runnable封装到Message中,返回的是Message。
private static Message getPostMessage(Runnable r) {
Message m = Message.obtain();
m.callback = r;
return m;
}
post(Runnable r),runnalbe是运行在和Handler绑定的线程中,并不是新开了线程运行的。如果创建Handler的线程是主线程就运行在主线程当中。
Handler在实际应用中大多都是应用于更新UI,因为必须在主线程更新UI,不能在子线程中更新。
在子线程当中更新时会报CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
看一下sendMessageDelayed方法:
public final boolean sendMessageDelayed(Message msg, long delayMillis){
if (delayMillis < 0) {
delayMillis = 0;
}
return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
}
又调用了sendMessageAtTime方法。
public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
MessageQueue queue = mQueue;
if (queue == null) {
RuntimeException e = new RuntimeException(
this + " sendMessageAtTime() called with no mQueue");
Log.w("Looper", e.getMessage(), e);
return false;
}
return enqueueMessage(queue, msg, uptimeMillis);
}
在这里看到了MessageQueue 。
MessageQueue queue = mQueue;
这里返回到Handler的构造方法:(当你使用无参的构造方式时最终会调用该构造方法)
public Handler(Callback callback, boolean async) {
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();
if (mLooper == null) {
throw new RuntimeException(
"Can't create handler inside thread that has not called Looper.prepare()");
}
mQueue = mLooper.mQueue;
mCallback = callback;
mAsynchronous = async;
}
从这里可以看到MessageQueue 是Looper当中的MessageQueue 。
在sendMessageAtTime当中我们可以看到它调用了enqueueMessage()。
private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
msg.target = this;
if (mAsynchronous) {
msg.setAsynchronous(true);
}
return queue.enqueueMessage(msg, uptimeMillis);
}
在该方法中,msg.target = this;(可以看出msg.target是Handler),然后调用了(MessageQueue 的queue.enqueueMessage方法
加入消息队列。此处就不展开了。
Looper:用于线程轮询信息。默认线程是没有Looper的。可以调用prepare()方法来为线程创建Looper.创建有Looper线程的例子:
class LooperThread extends Thread {
public Handler mHandler;
public void run() {
Looper.prepare();
mHandler = new Handler() {
public void handleMessage(Message msg) {
// process incoming messages here
}
};
Looper.loop();
}
}
在主线程中创建Handler时不用调用Looper.prepare()方法是因为在程序启动的时候,系统已经帮我们自动调用了Looper.prepare()方法。
loop()方法,就是一直循环查询MessageQueue。
public static void loop() {
final Looper me = myLooper();
if (me == null) {
throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
}
final MessageQueue queue = me.mQueue;
// Make sure the identity of this thread is that of the local process,
// and keep track of what that identity token actually is.
Binder.clearCallingIdentity();
final long ident = Binder.clearCallingIdentity();
for (;;) {
Message msg = queue.next(); // might block
if (msg == null) {
// No message indicates that the message queue is quitting.
return;
}
// This must be in a local variable, in case a UI event sets the logger
Printer logging = me.mLogging;
if (logging != null) {
logging.println(">>>>> Dispatching to " + msg.target + " " +
msg.callback + ": " + msg.what);
}
msg.target.dispatchMessage(msg);
if (logging != null) {
logging.println("<<<<< Finished to " + msg.target + " " + msg.callback);
}
// Make sure that during the course of dispatching the
// identity of the thread wasn't corrupted.
final long newIdent = Binder.clearCallingIdentity();
if (ident != newIdent) {
Log.wtf(TAG, "Thread identity changed from 0x"
+ Long.toHexString(ident) + " to 0x"
+ Long.toHexString(newIdent) + " while dispatching to "
+ msg.target.getClass().getName() + " "
+ msg.callback + " what=" + msg.what);
}
msg.recycle();
}
}
查看loop()方法的关键代码:
final Looper me = myLooper();//获取Looper
final MessageQueue queue = me.mQueue;//获取MessageQueue
for (;? {//循环
Message msg = queue.next()//从MessageQueue当中取出Message
msg.target.dispatchMessage(msg);
// msg.target就是Handler,调用Handler的dispatchMessage方法。
msg.recycle();
}
查看Handler的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是什么?当你是使用Handler的post(Runnable r)系列的方法时,msg.callback=runnable。所以Handler发送信息使用的是
post()方法时调用handleCallback(msg),使用send()方法则调用的是handleMessage()。
查看handleCallback(msg)方法:
private static void handleCallback(Message message) {
message.callback.run();
}
我们发现的是调用了Runnable的run()方法。而不是新启线程调用start()。所以Handler的post(Runnable runnable)参数runnable是运行在Handler绑定的线程,而不是新启线程运行。