优就业Android教程深入理解Android异步消息处理机制.docx
- 文档编号:29286995
- 上传时间:2023-07-21
- 格式:DOCX
- 页数:5
- 大小:27.20KB
优就业Android教程深入理解Android异步消息处理机制.docx
《优就业Android教程深入理解Android异步消息处理机制.docx》由会员分享,可在线阅读,更多相关《优就业Android教程深入理解Android异步消息处理机制.docx(5页珍藏版)》请在冰豆网上搜索。
优就业Android教程深入理解Android异步消息处理机制
优就业Android教程-深入理解Android异步消息处理机制
一、概述
Android中的异步消息处理主要分为四个部分组成,Message、Hndler、MessageQueue和Looper。
其关系如下图所示:
1.Message是线程之间传递的消息,它可以在内部携带少量信息,用于在不同线程之间交换数据。
2.MessageQueue是消息队列,它主要用于存放所有由Handler发送过来的消息,这部分消息会一直在消息队列中,等待被处理。
每个线程中只会有一个MessageQueue对象。
3.Handler是处理者,它主要用于发送和处理消息。
发送消息一般使用handler的sendMessage()方法,处理消息会调用handleMessage()方法。
4.Looper是每个线程中MessageQueue的管家,调用loop()方法后,就会进入到一个无限循环当中,然后每当发现MessageQueue中存在一条消息,就会将其取出,并传递到handleMessage()方法当中。
每个线程中也只会有一个Looper对象。
二、详细介绍
1、Looper
对于Looper主要是prepare()和loop()两个方法。
publicstaticfinalvoidprepare(){
if(sThreadLocal.get()!
=null){
thrownewRuntimeException("OnlyoneLoopermaybecreatedperthread");
}
sThreadLocal.set(newLooper(true));
}
sThreadLocal是一个ThreadLocal对象,可以在一个线程中存储变量。
Looper就是存储在sThreadLocal里面。
这个方法被调用后,首先会判断当前线程里面有没有Looper对象,如果没有就会创建一个Looper对象,如果存在则会抛出异常。
可见,prepare()方法,不能被调用两次。
这就保证了一个线程只有一个Looper对象。
接下来我们看一下Looper的构造函数:
privateLooper(booleanquitAllowed){
mQueue=newMessageQueue(quitAllowed);
mRun=true;
mThread=Thread.currentThread();
}
在Looper的构造函数中,创建了MessageQueue对象,这也保证了一个线程只有一个MessageQueue对象。
然后我们看看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("<<<< } //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.recycle(); } } 这个方法先调用myLooper()方法,得到sThreadLocal中保存的Looper对象,并得到looper对象对应的MessageQueue对象,然后就进入无限循环。 该循环主要包括: 取出一条消息,如果没有消息则阻塞;调用msg.target.dispatchMessage(msg);把消息交给msg的target的dispatchMessage方法去处理。 Looper主要作用: 1、与当前线程绑定,保证一个线程只会有一个Looper实例,同时一个Looper实例也只有一个MessageQueue。 2、loop()方法,不断从MessageQueue中去取消息,交给消息的target属性的dispatchMessage去处理。 2、Handler 在使用Handler之前,我们都是初始化一个实例,比如用于更新UI线程,我们会在声明的时候直接初始化,或者在onCreate中初始化Handler实例。 privateHandlermHandler=newHandler() { publicvoidhandleMessage(android.os.Messagemsg) { switch(msg.what) { casevalue: break; default: break; } }; }; 三、小结 1、首先Looper.prepare()在本线程中保存一个Looper实例,然后该实例中保存一个MessageQueue对象;因为Looper.prepare()在一个线程中只能调用一次,所以MessageQueue在一个线程中只会存在一个。 大家可能还会问,那么在Activity中,我们并没有显示的调用Looper.prepare()和Looper.loop()方法,为啥Handler可以成功创建呢,这是因为在Activity的启动代码中,已经在当前UI线程调用了Looper.prepare()和Looper.loop()方法 2、Looper.loop()会让当前线程进入一个无限循环,不端从MessageQueue的实例中读取消息,然后回调msg.target.dispatchMessage(msg)方法。 3、Handler的构造方法,会首先得到当前线程中保存的Looper实例,并与Looper实例中的MessageQueue相关联。 4、Handler的sendMessage方法,会给msg的target赋值为handler自身,然后加入MessageQueue中。 5、在构造Handler实例时,我们会重写handleMessage方法,也就是msg.target.dispatchMessage(msg)最终调用的方法。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 就业 Android 教程 深入 理解 异步 消息 处理 机制
![提示](https://static.bdocx.com/images/bang_tan.gif)