Android Handler消息派发机制源码分析
注:这里只是说一下sendmessage的一个过程,post就类似的
如果我们需要发送消息,会调用sendMessage方法
publicfinalbooleansendMessage(Messagemsg) { returnsendMessageDelayed(msg,0); }
这个方法会调用如下的这个方法
publicfinalbooleansendMessageDelayed(Messagemsg,longdelayMillis) { if(delayMillis<0){ delayMillis=0; } returnsendMessageAtTime(msg,SystemClock.uptimeMillis()+delayMillis); }
接下来设定延迟时间,然后继续调用sendMessageAtTime方法
publicbooleansendMessageAtTime(Messagemsg,longuptimeMillis){ MessageQueuequeue=mQueue; if(queue==null){ RuntimeExceptione=newRuntimeException( this+"sendMessageAtTime()calledwithnomQueue"); Log.w("Looper",e.getMessage(),e); returnfalse; } returnenqueueMessage(queue,msg,uptimeMillis); }
这里获得了消息队列,检查队列是否存在,然后返回enqueMessage的方法的执行结果,这个结果是说明消息能否进入队列的一个布尔值
privatebooleanenqueueMessage(MessageQueuequeue,Messagemsg,longuptimeMillis){ msg.target=this; if(mAsynchronous){ msg.setAsynchronous(true); } returnqueue.enqueueMessage(msg,uptimeMillis); }
这里是对消息进行入队处理,下面就是在MessageQueue中对消息进行入队
booleanenqueueMessage(Messagemsg,longwhen){ if(msg.target==null){ thrownewIllegalArgumentException("Messagemusthaveatarget."); } if(msg.isInUse()){ thrownewIllegalStateException(msg+"Thismessageisalreadyinuse."); } synchronized(this){ if(mQuitting){ IllegalStateExceptione=newIllegalStateException( msg.target+"sendingmessagetoaHandleronadeadthread"); Log.w(TAG,e.getMessage(),e); msg.recycle(); returnfalse; } msg.markInUse(); msg.when=when; Messagep=mMessages; booleanneedWake; if(p==null||when==0||when<p.when){ //Newhead,wakeuptheeventqueueifblocked. msg.next=p; mMessages=msg; needWake=mBlocked; }else{ //Insertedwithinthemiddleofthequeue.Usuallywedon'thavetowake //uptheeventqueueunlessthereisabarrierattheheadofthequeue //andthemessageistheearliestasynchronousmessageinthequeue. needWake=mBlocked&&p.target==null&&msg.isAsynchronous(); Messageprev; for(;;){ prev=p; p=p.next; if(p==null||when<p.when){ break; } if(needWake&&p.isAsynchronous()){ needWake=false; } } msg.next=p;//invariant:p==prev.next prev.next=msg; } //WecanassumemPtr!=0becausemQuittingisfalse. if(needWake){ nativeWake(mPtr); } } returntrue; }
就是对传递过来的消息进行一些封装然后放到队列中,至此我们的sendMessage处理完毕,返回的结果是进队是否成功的布尔值,那么究竟消息之后是如何被处理的呢?
我们可以看到在Handler构造的时候记录了一个Looper对象,也记录了一个回掉函数
publicHandler(Callbackcallback,booleanasync){ if(FIND_POTENTIAL_LEAKS){ finalClass<?extendsHandler>klass=getClass(); if((klass.isAnonymousClass()||klass.isMemberClass()||klass.isLocalClass())&& (klass.getModifiers()&Modifier.STATIC)==0){ Log.w(TAG,"ThefollowingHandlerclassshouldbestaticorleaksmightoccur:"+ klass.getCanonicalName()); } } mLooper=Looper.myLooper(); if(mLooper==null){ thrownewRuntimeException( "Can'tcreatehandlerinsidethreadthathasnotcalledLooper.prepare()"); } mQueue=mLooper.mQueue; mCallback=callback; mAsynchronous=async; }
这里的myLooper方法返回的是当前线程关联的一个Looper对象
publicstatic@NullableLoopermyLooper(){ returnsThreadLocal.get(); }
当Looper实例化了以后会执行自己的prepare方法然后执行loop方法,loop方法就是不断的读取消息队列中的消息然后执行相应的操作的方法,因为是在其他线程中执行的循环所以不会影响其他线程
publicstaticvoidloop(){ finalLooperme=myLooper(); if(me==null){ thrownewRuntimeException("NoLooper;Looper.prepare()wasn'tcalledonthisthread."); } finalMessageQueuequeue=me.mQueue; //Makesuretheidentityofthisthreadisthatofthelocalprocess, //andkeeptrackofwhatthatidentitytokenactuallyis. Binder.clearCallingIdentity(); finallongident=Binder.clearCallingIdentity(); for(;;){ Messagemsg=queue.next();//mightblock if(msg==null){ //Nomessageindicatesthatthemessagequeueisquitting. return; } //Thismustbeinalocalvariable,incaseaUIeventsetsthelogger Printerlogging=me.mLogging; if(logging!=null){ logging.println(">>>>>Dispatchingto"+msg.target+""+ msg.callback+":"+msg.what); } msg.target.dispatchMessage(msg); if(logging!=null){ logging.println("<<<<<Finishedto"+msg.target+""+msg.callback); } //Makesurethatduringthecourseofdispatchingthe //identityofthethreadwasn'tcorrupted. finallongnewIdent=Binder.clearCallingIdentity(); if(ident!=newIdent){ Log.wtf(TAG,"Threadidentitychangedfrom0x" +Long.toHexString(ident)+"to0x" +Long.toHexString(newIdent)+"whiledispatchingto" +msg.target.getClass().getName()+"" +msg.callback+"what="+msg.what); } msg.recycleUnchecked(); } }
在循环中如果读取到了消息,就会执行dispatchMessage方法,然后分派完消息之后再执行一次recycleUnchecked方法来重用这个Message,我们看到dispatchMessage方法
publicvoiddispatchMessage(Messagemsg){ if(msg.callback!=null){ handleCallback(msg); }else{ if(mCallback!=null){ if(mCallback.handleMessage(msg)){ return; } } handleMessage(msg); } }
这里看到直接执行了一个handlerMessage方法,这个方法是一个回调方法,我们是必须实现的,否则Handler什么都不会做,为什么呢?还记得刚刚说构造Handler的时候我们记录了一个CallBack的回掉吗?Handler中的这个handlerMessage方法是一个空方法,如果我们重写了这个方法,在回调的时候就会执行我们先写下的代码,也就是接收到消息之后要做什么。
publicinterfaceCallback{ publicbooleanhandleMessage(Messagemsg); } publicvoidhandleMessage(Messagemsg){ }
这里简单说下整个过程:
当我们实例化一个Handler的子类并重写handleMessage方法之后,这个时候系统已经帮我们做了几个事情
1.实例化了一个消息队列MessageQueue
2.实例化了一个关联的Looper对象,并让Looper不断的读取消息队列
3.把我们重写的handleMessage方法记录为我们需要回调的方法
当我们执行Handler的sendMessage方法的时候,系统会把我们传过去的Message对象添加到消息队列,这个时候如果Looper读取到了消息,就会把消息派发出去,然后回调handleMessage方法,执行我们设定的代码。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。