Handler的官方解释大致意思如下:
Handler是一种能够发送和处理与消息队列关联的Message和Runnable的一种对象。它隶属于调用Handler对象的线程,自它创建伊始,它就在当前线程发送消息到当前线程的消息队列,并且负责处理线程消息队列的消息。
Handler的用法主要有两种:其一,发送消息,其二,在另外一个线程处理消息。
对其一:
post(Runnable),postAtTime(Runnable,long),postDelayed(Runnable,long),sendEmptyMessage(int),sendMessage(Message),sendMessageAtTime(Message,long),andsendMessageDelayed(Message,long)这些方法主要用来发送消息,其中,postversion主要是发送Runnable,而sendMessageversion则是用来发送消息,然后在handler的HandleMessage中处理。
如何处理的呢?最后一段非常关键:当我们创建了一个应用程序进程,它内部就开启了一个处理消息的Looper.
在new一个Handler的时候,
mLooper=Looper.myLooper();
publicstaticfinalLoopermyLooper(){
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。
相关代码:
发送消息:
publicfinalbooleansendMessage(Messagemsg)
{
returnsendMessageDelayed(msg,0);
}-------->
---->
publicfinalbooleansendMessageDelayed(Messagemsg,longdelayMillis)
{
if(delayMillis<0){
delayMillis=0;
}
returnsendMessageAtTime(msg,SystemClock.uptimeMillis()+delayMillis);
}------>
-------->
publicbooleansendMessageAtTime(Messagemsg,longuptimeMillis)
{
booleansent=false;
MessageQueuequeue=mQueue;
if(queue!=null){
msg.target=this;
sent=queue.enqueueMessage(msg,uptimeMillis);
}
else{
RuntimeExceptione=newRuntimeException(
this+"sendMessageAtTime()calledwithnomQueue");
Log.w("Looper",e.getMessage(),e);
}
returnsent;
}
可见发送消息就是将Message加入消息队列。
处理消息:
publicstaticfinalvoidloop(){
Looperme=myLooper();
MessageQueuequeue=me.mQueue;
Binder.clearCallingIdentity();
finallongident=Binder.clearCallingIdentity();
while(true){
Messagemsg=queue.next();//获取下一个Message,可能会block
if(msg!=null){
if(msg.target==null){
return;
}
msg.target.dispatchMessage(msg);
finallongnewIdent=Binder.clearCallingIdentity();
if(ident!=newIdent){
Log.wtf("Looper","Threadidentitychangedfrom0x"
+Long.toHexString(ident)+"to0x"
+Long.toHexString(newIdent)+"whiledispatchingto"
+msg.target.getClass().getName()+""
+msg.callback+"what="+msg.what);
}
msg.recycle();
}
}
也就是Loop循环不断从消息队列中获取消息进行处理:其实就是调用callback的过程。
Runnable处理流程:
现在来分析:发送流程:
Runnableruna=newRunnable(){
publicvoidrun(){
//TODOAuto-generatedmethodstub
}
}
然后HandlermHandler=newHandler();
mHandler.post(runna);
publicfinalbooleanpost(Runnabler)
{
returnsendMessageDelayed(getPostMessage(r),0);
}
官方解释是:CausestheRunnablertobeaddedtothemessagequeue.也就是将Runnable加入到Message队列,怎么变成消息的呢?
接着往下看:
publicfinalbooleanpost(Runnabler)
{
returnsendMessageDelayed(getPostMessage(r),0);
}----->
sendMessageDelayed(getPostMessage(r),0)--->
------>
publicfinalbooleansendMessageDelayed(Messagemsg,longdelayMillis)
{
if(delayMillis<0){
delayMillis=0;
}
returnsendMessageAtTime(msg,SystemClock.uptimeMillis()+delayMillis);
}
在上一步,决定何时发送,是否延时发送。
getPostMessage()函数原型如下:
privatefinalMessagegetPostMessage(Runnabler){
Messagem=Message.obtain();
m.callback=r;
returnm;
}
在这里我们看到,Message.obtain()获取一个Message实例,然后将Runnable加入到Message的callback中,也就是封装成一个Message了。之后在大循环中进行处理。
到此,对于Handler发送Message也就很容易理解了,只不过把runnable改变成Message放到消息队列中去,然后就开始处理。