Handler的官方解释大致意思如下:
Handler是一种能够发送和处理与消息队列关联的Message和Runnable的一种对象。它隶属于调用Handler对象的线程,自它创建伊始,它就在当前线程发送消息到当前线程的消息队列,并且负责处理线程消息队列的消息。
Handler的用法主要有两种:其一,发送消息,其二,在另外一个线程处理消息。
对其一:
post(Runnable), postAtTime(Runnable, long), postDelayed(Runnable, long), sendEmptyMessage(int), sendMessage(Message), sendMessageAtTime(Message, long), and sendMessageDelayed(Message, long) 这些方法主要用来发送消息,其中,post version主要是发送Runnable,而sendMessage version则是用来发送消息,然后在handler的HandleMessage中处理。
如何处理的呢?最后一段非常关键:当我们创建了一个应用程序进程,它内部就开启了一个处理消息的Looper.
在new一个Handler的时候,
mLooper = Looper.myLooper();
public static final Looper myLooper() {
return (Looper)sThreadLocal.get();
}
mQueue = mLooper.mQueue;
mCallback = callback;
获取当前进程的Looper,然后获取它的消息队列,这样就将一个消息加入了消息队列,这个Looper开启类似下面,先运行Run方法,在Run方法中Looper.prepare,之后进入一个无限循环,Looper.loop(),在这里处理消息。在处理消息时调用callback,也就是HandleMessage或者Run开始处理。
因此,在用Handler的时候有两点需要注意:
一是callback函数,二时Post/sendMessage,callback为处理Message,而Post/sendMessage则是发送Message。
相关代码:
发送消息:
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);
}
else {
RuntimeException e = new RuntimeException(
this + " sendMessageAtTime() called with no mQueue");
Log.w("Looper", e.getMessage(), e);
}
return sent;
}
可见发送消息就是将Message加入消息队列。
处理消息:
public static final void loop() {
Looper me = myLooper();
MessageQueue queue = me.mQueue;
Binder.clearCallingIdentity();
final long ident = Binder.clearCallingIdentity();
while (true) {
Message msg = queue.next(); //获取下一个Message,可能会block
if (msg != null) {
if (msg.target == null) {
return;
}
msg.target.dispatchMessage(msg);
final long newIdent = Binder.clearCallingIdentity();
if (ident != newIdent) {
Log.wtf("Looper", "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循环不断从消息队列中获取消息进行处理:其实就是调用callback的过程。
Runnable处理流程:
现在来分析:发送流程:
Runnable runa = new Runnable() {
public void run() {
// TODO Auto-generated method stub
}
}
然后Handler mHandler = new Handler();
mHandler.post(runna);
public final boolean post(Runnable r)
{
return sendMessageDelayed(getPostMessage(r), 0);
}
官方解释是:Causes the Runnable r to be added to the message queue.也就是将Runnable加入到Message队列,怎么变成消息的呢?
接着往下看:
public final boolean post(Runnable r)
{
return sendMessageDelayed(getPostMessage(r), 0);
}----->
sendMessageDelayed(getPostMessage(r), 0)--->
------>
public final boolean sendMessageDelayed(Message msg, long delayMillis)
{
if (delayMillis < 0) {
delayMillis = 0;
}
return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
}
在上一步,决定何时发送,是否延时发送。
getPostMessage()函数原型如下:
private final Message getPostMessage(Runnable r) {
Message m = Message.obtain();
m.callback = r;
return m;
}
在这里我们看到,Message.obtain()获取一个Message实例,然后将Runnable加入到Message的callback中,也就是封装成一个Message了。之后在大循环中进行处理。
到此,对于Handler发送Message也就很容易理解了,只不过把runnable改变成Message放到消息队列中去,然后就开始处理。