Android中消息系统模型和Handler Looper.docx

上传人:太** 文档编号:96936967 上传时间:2024-04-07 格式:DOCX 页数:19 大小:66.64KB
返回 下载 相关 举报
Android中消息系统模型和Handler Looper.docx_第1页
第1页 / 共19页
Android中消息系统模型和Handler Looper.docx_第2页
第2页 / 共19页
点击查看更多>>
资源描述

《Android中消息系统模型和Handler Looper.docx》由会员分享,可在线阅读,更多相关《Android中消息系统模型和Handler Looper.docx(19页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。

1、Android中消息系统模型和Handler Looper作为Android中大量使用的Handler,结合Thread使其具有众多的使用形式和方法,让我一时感觉这个东西有些玄乎,不明所以然,这到底是一个什么样 的存在呢?通过网上资料和源码的学习,这个Handler也差不多弄清楚了,现在总结下 这个学习结果。-Handler作用和概念通过官方文档了解到Handler的大致概念是:Handler能够让你发送和处理消息,以及Runnable对象;每个Handler对象对应一个Thread和Thread的消息队列。当你创建一个Handler时,它就和Thread的消息队列绑定在一起,然后就可以传递消

2、息和runnable对象到消息队列中,执行消息后就从消息队列 中退出。Handler的作用就是:调度消息和runnable对象去被执行;使消息系统模型的核心是Loopero下面看看Handler是如何建立跑起来的,以msg消息为例,runnable实质是一样。1 Handler的建立Handler唯一属于某个Thread,在某个Thread中建立Hand ler时,需要获取Thread的Looper及其MessageQueue,建立Handler关键是Looper的来源。Handler提供了好几个构造函数但其本质一致:由外部传入Looper:当前线程或其他线程电public Handler(L

3、ooper looper) /初始化构建消息系统参数mLooper = ;mQueue = looper.mQueue;mCallback = null;)电从当前线程获取:由创建Handler的Thread决定电public Handler () /初始化构建消息系统参数mLooper = www .12youhui . com r.myLooper();mQueue = mLooper.mQueue;mCallback = null;public static Looper myLooper() return sThreadLocal.get (); 电不管哪种方式,我们知道Thread在

4、默认情况下是没有建立消息循环Looper实例的。要实现消息循环必须确保Thread的Looper建立。如何确保呢?Looper提供了静态函数:电public static void prepare () if (sThreadLocal .get () ! = null) throw new RuntimeException (nOnly one Loop工 may be cr eated per www. cp0 61 , comn);)sThreadLocal.set(new Looper (); /存储线程的局部变量static final ThreadLocal sThreadLoca

5、l = new ThreadLocal ();电看到这里刚开始让我很是奇怪和迷惑:Looper 一个独立的类,又不属于某个Thread,而这里创建Lo oper的函数又是静态的,属于整个Looper类;创建Looper之后交给静态成员变量sThreadLocal保存,获取sThreadLocal.get(),那么一个静态变量属于整个类,属性更改始 终有效。一次创建之后sThreadLocal.get。永远都不等于 null!而Thread和Looper是唯一对应的,那这里岂不是所有的Thr ead都是用同一个Looper,不可能!所以肯定这个ThreadLocal是有玄机的。网上一查:Thre

6、adLocal:维护线程的变量,为每个使用该变量的线程实例提供独立的 变量副本,每个线程都能够独立使用该变量,而互不影响。(详细可参考:)所以每一个线程调用Looper.prepare 0t,都会创建为其唯一的 Loopero要建立Handler,需要先创建线程的Looper,才能建立消息系 统模型。通过Looper我们建立了Thread上的消息系统模型Handler,可以来进行消息系统的一系列 流程了。2消息发送消息发送两种方式:post sendMessage;post:针对runnable对象;Runnable是一个接口,就是一个回调函数(提供了 run方法)sendMessage:针对

7、 Message 对象;下面通过代码具体看一下这个过程:电public final boolean post( www , scujuu , com r) return sendMessag D layed (get PostMes sage (r) , 0);)public final boolean sendMessage(Message msg) return sendMessageDelayed (msg, 0); 电看到post和sendMessage发送消息时,仅仅是对象不同而已,Runnable 和 Message;但实际上都是Message的形式来描述。这跟我通常理解的消息机制

8、不同:通常post消息是将消息加入到消息队列中并不立即执行就返 回,send消息是立即执行等待消息执行完才返回。而这里post或者send都是将消息放入到消息队列中,然后立即返回,等待消息循环时获取消息被执行。这里提供了众多的消息发送方法来指定消息的执行时间和顺序, 具体可以查看源代码。消息执行顺序是根据消息队列中消息的排列顺序而定。下面看一下发送消息后将消息加入到消息队列中的代码:由 Handler 调用 MessageQueue 的 enqueueMessage 方法:final boolean enqueueMessage (Message msg, long when) Message

9、 p = mMessages;if (p = null | | when = 0 | | when p.when) msg. www.bboby. com = p;mMessages = msg;)else Message prev = null;while (p ! = null & & p, when = when) prev = p;p = p.next; )msg.next = prev.next; prev.next = msg;)可以看到是按照时间顺序将消息加入到MessageQueue中;现在将消息加入到消息队列中存储起来,消息并未得到处理,下一步 必然是如何派发消息和处理消息。

10、3消息派发建立Thread消息循环由Looper完成,存在一个消息调度死循环:电public static void loop () MessageQueue queue = me.mQueue; while (true) Message msg = queu next ( ) ;/ might block if (msg ! = null) if (msg. target = null) / No target is a magic identifier for the quit messag e.return; )/派发消息至U target (Handler) msg . target.

11、dispatchMessage(msg);/回收 Msg 至ImsgPool msg. www .12youhui . com e();) )电这里看到消息派发是由Message的target完成,这个target是什么呢?是一个Handler。消息系统是通过Handle用来与外部交互,把消息派发出去。可以 看到没有这个Handler,消息循环将结束。消息派发由Looper通过Handler完成:电public void dispatchMessage(Message msg) /首先判断runnable对象if (msg. callback ! = null) handlecallback(

12、msg);)else /整个消息系统的回调函数 可以不用实现自己Handler if (mCallback ! = null) if (mCallback.handleMessage(msg) return;)/消息处理 通常交给Handler派生类 handleMessage(msg);)电通过消息派发,这样就实现消息的异步处理。4消息原型前面看到消息发送有两种方式: post (Runnable 对象),sendMessage (Message 对象),而中间都是通过Message对象保存在MessageQueue中。然后消息派发时处理方式不同。如果在sendMessage时将将消息对象附

13、上Runnable对象,贝ij post和sendMessage没有区另U了。所以 这两种方式很好理解基本一致,处理的方式不同罢了。消息系统模型中,我们的真正的消息原型是什么,都具有那些功 能,下面看一下Message中到底包含了那些东西,能有效帮助我们合理的运用消息系统来完成一些任务和处理。Message消息原型:电public final class Message implements Parcelable /标识消息public int what;int flags; long when;/传递简单数据 public int argl;public int arg2;/传递较复杂数据对

14、象 public Object obj;Bundle data;/处理消息的目标Handler Handler target;/消息派发时 执行的Rurmabl对象Runnable callback;/使消息形成链表Message next;/建立一个消息P。1,回收msg,以避免重复创建节约开销 private static Message sPool;private static int sPoolSize = 0;private static final int MAX POOL SI ZE = 10;)电看到提供了很丰富的属性来描述消息,针对具体问题选择使用那 些属性去怎么样描述消息了

15、。获取新的Message对象时,Message提供了 obtain方法:避免我们自己去分配Message新的对象,通过obtain获取,可能从MessagePool中获取,节约开销。下面看一下这个MessagePool是如何建立的:通常消息处理完毕的时候,消息也基本上处于无用状态可以释放回收了。对于需要频繁的创建释放的对象来说,创建和释放类实例都是要开销的,太频繁的使开销增大不好,像Me ssage这种很有可能会频繁的创建。于是我们可以将创建的对象用完之后保存在一个Pool里面,以 便再重复利用节约频繁创建释放开销。是如何建立的呢?必然是在消息处理完毕之后才能进行。MessagePool 建立

16、:电public static void loop () while (true) /派发消息msgtarget.dispatchMessage(msg);/消息处理完毕回收msg.recycle ();)public void recycle() /回收Message 建立全局的MessagePoolif (sPoolSize MAX_POOL_SIZE) next = sPool;sPool = this; sPoolSize + + ;电五Handler的应用以上这就是整个Handler作用及消息系统模型的建立。使用也非常简单,虽然有很多方式,但只要理解Handler是建立在Looper

17、 ,实现Thread 的消息系统处理模型,实现消息异步处理,我想对与Handler基本应用上没有什么不能理解的了。其他方面可以去看源码了。Handle使用起来是非常简单的,关键就是如何利用消息的异步处理,来合理的完成我们当一个应用程序中进程被创建时,它的主线程专门运行消息队列(messageQueue),去管理顶层的应用程序相关的对象如:activity, broadcastReceiver, windows等,你可以创建你的Thread,和主线程进行交互一一通过Handler,交互的方法就是通过 post 或者 sendMessageo但是在你的新线程中,给定的Message或者Runnab

18、le,会在适当 的时候的被调度和处理。(即不会被立即处理一一阻塞式)。这是官方文档中对Handler描述的大致意思(英文比较烂翻译 不定正确)。从这些文档中我们大概了解到handler干了些什么: 运行在某个线程上,共享线程的消息队列; 接收消息、调度消息,派发消息和处理消息; 实现消息的异步处理;基本上就是和消息有关,那么这实际上是在干什么呢?一一建立消息处理模型/系统。 需要功能和任务。对于一个Thread,我们使用好几个Handler来进 行异步处理,也可以创建新的Thread,通过Handler来实现消息异步处理等等,应用场景很多如何用的好 用的合理,这就没什么经验了。至于如何使用,源

19、码中很多例子可以看一下AsyncQueryHa ndler这个类,其中两个线程,完成查询工作,通过Handler进行线程之间有消息传递。感觉这个 利用的很好很巧妙。要学习Handler,看到肯定是和消息有关,可能还是需要先熟悉一下消息系统的构成和简单原理。下面就先学习一下消息系统的基本原理。二消息系统的基本原理和构成从一般的消息系统模型的建立大致构成以下几个部分:I消息原型I消息队列I发送消息I消息循环I消息获取I消息派发I消息处理大致模型图如下:消息系统模型一般会包括以上七个部分(消息原型,消息队列,消息发送,消息循环,消息获取,消息派发,消息处理)。实际上的核心是消息队列和消息循环,其余

20、部分都是围绕这两部分进行的。从前面文档的分析中我们知道Handler就是用来建立消息处理的系统模型,那么和这里基本消息系统模型相比,那么Handler又是如何囊括这七个部分的呢?在Android中对这六个部分进行了抽象成四个独立的部分:Handler, Message, MessageQueue, Looper; Message就是消息原型,包含消息描述和数据, MessageQueue就是消息队列, Looper完成消息循环 Handler就是驾驭整个消息系统模型,统领Message, MessgeQueue 和 Looper;Handler能够实现消息系统模型,那么具体是如何进行工作的 呢

21、,下面探究一下这其中工作的方法和原理。三Handler工作原理分析要了解Handler工作原理,先看一下这个系统模型具体组成的层次结构框架是个什么样的。Looper:实现Thread的消息循环和消息派发,缺省情况下Thread是没有这个消息循环的既没有Looper;需要主动去创建,然后启动Looper的消息循环loop;与外部的交互通过Handler进行;MessageQueue:消息队列,由Looper所持有,但是消息的添加是通过Handler进行;消息循环和消息队列都是属于Thread,而Handler本身并不具有 Looper 和 MessageQueue;但是消息系统的建立和交互,是T

22、hread将Looper和MessageQu eue交给某个Handler维护建立消息系统模型。所以消息系统模型的核心就是Loopero消息循环和消息队列都 是由Looper建立的,而建立Handler的关键就是这个Looper。一个Thread同时可以对应多个Handler, 一个Handler同时 只能属于一个Thread。Handler属于哪个Thread取决于Handler在那个Thread中建立。在一个Thread中Looper也是唯一的,一个Thread对应一个 Looper,建立 Handler 的 Looper 来自哪个Thread,Handler 属于哪个 Thread。故建

23、立Thread消息系统,就是将Thread的Looper交给Ha ndler去打理,实现消息系统模型,完成消息的异步处理。Handler与Thread及Looper的关系可以用下面图来表示:tch MsgHandler并不等于Thread,必须通过Thread的Looper及其 MessageQueue,用来实现Thread消息系统模型,依附于Thread上。在线程建立Handler时:使Handler满足消息系统需要的条件,将Thread中的Loope r和MessageQueue交给Handler来负责维护。在线程中建立Handler,需要做以下工作:I获取Thread中的Looper交给

24、Handler的成员变量引用维 护;I通过Looper获取MessageQueue交给Handler的成员变 量引用维护。那么消息系统模型建立完成之后,按照消息系统运行,从Handler来看就是发送消息派发消息、,与此线程消息系统的交互 者B由Handler完成。消息发送和派发接口:I post (runnable)消息,Runnable是消息回调,经过消息 循环引发消息回调函数执行;I sendMessage (Message)消息,经过消息循环派发消息处 理函数中处理消息;I dispatchMessage派发消息,若是post或带有回调函数则执行回调函数,否则执行消息处理函数Handler的handleMessage (通常派 生类重写)。以上就是Handler如何实现Thread消息系统模型的大致介绍。 下面将具体分析是如何实现消息系统模型运行的。U!Handler实现流程分析我们知道Handler就是一个消息系统的外壳,属于某个Thread 并包装了 Thread 的 Looper及其MessageQueue;与外部进行交互(同一个线程内或者线程之 间),接收派发和处理消息,

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 应用文书 > 解决方案

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知淘文阁网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号© 2020-2023 www.taowenge.com 淘文阁