Handler的处理

Handler的官方解释大致意思如下:

Handler是一种能够发送和处理与消息队列关联的MessageRunnable的一种对象。它隶属于调用Handler对象的线程,自它创建伊始,它就在当前线程发送消息到当前线程的消息队列,并且负责处理线程消息队列的消息。

Handler的用法主要有两种:其一,发送消息,其二,在另外一个线程处理消息。

对其一:

post(Runnable),postAtTime(Runnable,long),postDelayed(Runnable,long),sendEmptyMessage(int),sendMessage(Message),sendMessageAtTime(Message,long),andsendMessageDelayed(Message,long)这些方法主要用来发送消息,其中,postversion主要是发送Runnable,而sendMessageversion则是用来发送消息,然后在handlerHandleMessage中处理。

如何处理的呢?最后一段非常关键:当我们创建了一个应用程序进程,它内部就开启了一个处理消息的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/sendMessagecallback为处理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加入到Messagecallback中,也就是封装成一个Message了。之后在大循环中进行处理。

到此,对于Handler发送Message也就很容易理解了,只不过把runnable改变成Message放到消息队列中去,然后就开始处理。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值