Android Looper和Handler分析.docx

上传人:b****6 文档编号:7578624 上传时间:2023-01-25 格式:DOCX 页数:15 大小:23.32KB
下载 相关 举报
Android Looper和Handler分析.docx_第1页
第1页 / 共15页
Android Looper和Handler分析.docx_第2页
第2页 / 共15页
Android Looper和Handler分析.docx_第3页
第3页 / 共15页
Android Looper和Handler分析.docx_第4页
第4页 / 共15页
Android Looper和Handler分析.docx_第5页
第5页 / 共15页
点击查看更多>>
下载资源
资源描述

Android Looper和Handler分析.docx

《Android Looper和Handler分析.docx》由会员分享,可在线阅读,更多相关《Android Looper和Handler分析.docx(15页珍藏版)》请在冰豆网上搜索。

Android Looper和Handler分析.docx

AndroidLooper和Handler分析

AndroidLooper和Handler分析

第一次接触android应用程序(这里指的是JAVA层的UI程序,也难怪了,Google放出的API就只支持JAVA应用程序了),很难搞明白内部是如何实现的。

但是,从原理上分析,应该是有一个消息循环,一个消息队列,然后主线程不断得从消息队列中取得消息并处理之。

然而,google封装得太厉害了,所以一时半会还是搞不清楚到底是怎么做的。

本文将分析android内的looper,这个是用来封装消息循环和消息队列的一个类,handler其实可以看做是一个工具类,用来向消息队列中插入消息的。

好比是WindowsAPI的SendMessage中的HANDLE,这个handle是窗口句柄。

//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循环的时候会打印相关信息,用来调试用最好了。

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

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 经管营销 > 经济市场

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1