+msg.callback);
msg.recycle();
}
}
}
/**
*ReturntheLooperobjectassociatedwiththecurrentthread.Returns
*nullifthecallingthreadisnotassociatedwithaLooper.
*/
//返回和线程相关的looper
publicstaticfinalLoopermyLooper(){
return(Looper)sThreadLocal.get();
}
/**
*ControlloggingofmessagesastheyareprocessedbythisLooper.If
*enabled,alogmessagewillbewrittentoprinter
*atthebeginningandendingofeachmessagedispatch,identifyingthe
*targetHandlerandmessagecontents.
*
*@paramprinterAPrinterobjectthatwillreceivelogmessages,or
*nulltodisablemessagelogging.
*/
//设置调试输出对象,looper循环的时候会打印相关信息,用来调试用最好了。
publicvoidsetMessageLogging(Printerprinter){
mLogging=printer;
}
/**
*Returnthe{@linkMessageQueue}objectassociatedwiththecurrent
*thread.ThismustbecalledfromathreadrunningaLooper,ora
*NullPointerExceptionwillbethrown.
*/
publicstaticfinalMessageQueuemyQueue(){
returnmyLooper().mQueue;
}
//创建一个新的looper对象,
//内部分配一个消息队列,设置mRun为true
privateLooper(){
mQueue=newMessageQueue();
mRun=true;
mThread=Thread.currentThread();
}
publicvoidquit(){
Messagemsg=Message.obtain();
//NOTE:
Byenqueueingdirectlyintothemessagequeue,the
//messageisleftwithanulltarget.Thisishowweknowitis
//aquitmessage.
mQueue.enqueueMessage(msg,0);
}
/**
*ReturntheThreadassociatedwiththisLooper.
*/
publicThreadgetThread(){
returnmThread;
}
//后面就简单了,打印,异常定义等。
publicvoiddump(Printerpw,Stringprefix){
pw.println(prefix+this);
pw.println(prefix+"mRun="+mRun);
pw.println(prefix+"mThread="+mThread);
pw.println(prefix+"mQueue="+((mQueue!
=null)?
mQueue:
"(null"));
if(mQueue!
=null){
synchronized(mQueue){
Messagemsg=mQueue.mMessages;
intn=0;
while(msg!
=null){
pw.println(prefix+"Message"+n+":
"+msg);
n++;
msg=msg.next;
}
pw.println(prefix+"(Totalmessages:
"+n+")");
}
}
}
publicStringtoString(){
return"Looper{"
+Integer.toHexString(System.identityHashCode(this))
+"}";
}
staticclassHandlerExceptionextendsException{
HandlerException(Messagemessage,Throwablecause){
super(createMessage(cause),cause);
}
staticStringcreateMessage(Throwablecause){
StringcauseMsg=cause.getMessage();
if(causeMsg==null){
causeMsg=cause.toString();
}
returncauseMsg;
}
}
}
Cpp代码
//Looper类分析
//没找到合适的分析代码的办法,只能这么来了。
每个重要行的上面都会加上注释
//功能方面的代码会在代码前加上一段分析
publicclassLooper{
//static变量,判断是否打印调试信息。
privatestaticfinalbooleanDEBUG=false;
privatestaticfinalbooleanlocalLOGV=DEBUG?
Config.LOGD:
Config.LOGV;
//sThreadLocal.get()willreturnnullunlessyou'vecalledprepare().
//线程本地存储功能的封装,TLS,threadlocalstorage,什么意思呢?
因为存储要么在栈上,例如函数内定义的内部变量。
要么在堆上,例如new或者malloc出来的东西
//但是现在的系统比如Linux和windows都提供了线程本地存储空间,也就是这个存储空间是和线程相关的,一个线程内有一个内部存储空间,这样的话我把线程相关的东西就存储到
//这个线程的TLS中,就不用放在堆上而进行同步操作了。
privatestaticfinalThreadLocalsThreadLocal=newThreadLocal();
//消息队列,MessageQueue,看名字就知道是个queue..
finalMessageQueuemQueue;
volatilebooleanmRun;
//和本looper相关的那个线程,初始化为null
ThreadmThread;
privatePrintermLogging=null;
//static变量,代表一个UIProcess(也可能是service吧,这里默认就是UI)的主线程
privatestaticLoopermMainLooper=null;
/**Initializethecurrentthreadasalooper.
*Thisgivesyouachancetocreatehandlersthatthenreference
*thislooper,beforeactuallystartingtheloop.Besuretocall
*{@link#loop()}aftercallingthismethod,andenditbycalling
*{@link#quit()}.
*/
//往TLS中设上这个Looper对象的,如果这个线程已经设过了looper的话就会报错
//这说明,一个线程只能设一个looper
publicstaticfinalvoidprepare(){
if(sThreadLocal.get()!
=null){
thrownewRuntimeException("OnlyoneLoopermaybecreatedperthread");
}
sThreadLocal.set(newLooper());
}
/**Initializethecurrentthreadasalooper,markingitasanapplication'smain
*looper.ThemainlooperforyourapplicationiscreatedbytheAndroidenvironment,
*soyoushouldneverneedtocallthisfunctionyourself.
*{@link#prepare()}
*/
//由framework设置的UI程序的主消息循环,注意,这个主消息循环是不会主动退出的
//
publicstaticfinalvoidprepareMainLooper(){
prepare();
setMainLooper(myLooper());
//判断主消息循环是否能退出....
//通过quit函数向looper发出退出申请
if(Process.supportsProcesses()){
myLooper().mQueue.mQuitAllowed=false;
}
}
privatesynchronizedstaticvoidsetMainLooper(Looperlooper){
mMainLooper=looper;
}
/**Returnstheapplication'smainlooper,whichlivesinthemainthreadoftheapplication.
*/
publicsynchronizedstaticfinalLoopergetMainLooper(){
returnmMainLooper;
}
/**
*Runthemessagequeueinthisthread.Besuretocall
*{@link#quit()}toendtheloop.
*/
//消息循环,整个程序就在这里while了。
//这个是static函数喔!
publicstaticfinalvoidloop(){
Looperme=myLooper();//从该线程中取出对应的looper对象
MessageQueuequeue=me.mQueue;//取消息队列对象...
while(true){
Messagemsg=queue.next();//mightblock取消息队列中的一个待处理消息..
//if(!
me.mRun){//是否需要退出?
mRun是个volatile变量,跨线程同步的,应该是有地方设置它。
//break;
//}
if(msg!
=null){
if(msg.target==null){
//Notargetisamagicidentifierforthequitmessage.
return;
}
if(me.mLogging!
=null)me.mLogging.println(
">>>>>Dispatchingto"+msg.target+""
+msg.callback+":
"+msg.what
);
msg.target.dispatchMessage(msg);
if(me.mLogging!
=null)me.mLogging.println(
"<<<<+msg.callback);
msg.recycle();
}
}
}
/**
*ReturntheLooperobjectassociatedwiththecurrentthread.Returns
*nullifthecallingthreadisnotassociatedwithaLooper.
*/
//返回和线程相关的looper
publicstaticfinalLoopermyLooper(){
return(Looper)sThreadLocal.get();
}
/**
*ControlloggingofmessagesastheyareprocessedbythisLooper.If
*enabled,alogmessagewillbewrittentoprinter
*atthebeginningandendingofeachmessagedispatch,identifyingthe
*targetHandlerandmessagecontents.
*
*@paramprinterAPrinterobjectthatwillreceivelogmessages,or
*nulltodisablemessagelogging.
*/
//设置调试输出对象,looper循环的时候会打印相关信息,用来调试用最好了。
public