《Android移动应用开发》应用程序的消息处理机制_第1页
《Android移动应用开发》应用程序的消息处理机制_第2页
《Android移动应用开发》应用程序的消息处理机制_第3页
《Android移动应用开发》应用程序的消息处理机制_第4页
《Android移动应用开发》应用程序的消息处理机制_第5页
已阅读5页,还剩20页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Handler消息传递机制2023/9/28072023/9/28消息处理机制消息处理对象目录CONTENT12异步加载图像示例3参考教材:《Android应用开发项目化教程》消息处理机制思路Android通过Looper、Handler来实现消息循环机制。Android的消息循环是针对线程的,每个线程都可以有自己的消息队列和消息循环。1消息处理机制核心对象Message消息,理解为线程间通讯的数据单元。MessageQueue消息队列,用来存放通过Handler发布的消息,按照先进先出执行。HandlerHandler是Message的主要处理者,负责将Message添加到消息队列以及对消息队列中的Message进行处理。1Looper循环器,扮演MessageQueue和Handler之间桥梁的角色,循环取出MessageQueue里面的Message,并交付给相应的Handler进行处理。线程每一个线程里可含有一个Looper对象以及一个MessageQueue数据结构。在应用程序里,可以定义Handler的子类别来接收Looper所送出的消息。消息处理机制一般处理流程包装Message对象(指定Handler、回调函数和携带数据等);通过Handler的sendMessage()等类似方法将Message发送出去;在Handler的处理方法里面将Message添加到Handler绑定的Looper的MessageQueue;Looper的loop()方法通过循环不断从MessageQueue里面提取Message进行处理,并移除处理完毕的Message;通过调用Message绑定的Handler对象的dispatchMessage()方法完成对消息的处理。1消息处理对象Looper被设计用来使一个普通线程变成Looper线程。Looper线程就是循环工作的线程。在程序开发中(尤其是GUI开发中),我们经常会需要一个线程不断循环,一旦有新任务则执行,执行完继续等待下一个任务,这就是Looper线程。每个线程有且最多只能有一个Looper对象,它是一个ThreadLocalLooper内部有一个消息队列MessageQueue,消息队列在Looper的构造函数中被创建并且作为成员变量被保存,也就是说MessageQueue相对于线程也是唯一的。loop()方法调用后线程开始不断从队列中取出消息执行Looper使一个线程变成Looper线程2消息处理对象Looper创建Looper线程Android应用在启动的时候会默认会为主线程创建一个Looper实例,并借助相关的Handler和Looper里面的MessageQueue完成对Activities、Services、BroadcaseReceivers等的管理。2消息处理对象Looper创建Looper线程而在子线程中,Looper需要通过显式调用Looper.Prepare()方法进行创建。Prepare方法通过ThreadLocal来保证Looper在线程内的唯一性,如果Looper在线程内已经被创建并且尝试再度创建"OnlyoneLoopermaybecreatedperthread"异常将被抛出。2消息处理对象Looper核心方法Looper.prepare()Looper.loop()不断从自己的MQ中取出队头的消息执行Looper.myLooper()得到当前线程Looper对象Looper.getThread()得到Looper对象所属线程Looper.quit()结束Looper循环2消息处理对象Handler被设计用来向MessageQueue中添加消息和处理消息。Handler只处理由自己发出的消息,即通知MessageQueue要执行一个任务(sendMessage()),并在loop()到自己的时候执行该任务(handleMessage()),整个过程是异步的。每个Handler都会与唯一的一个线程以及该线程的消息队列关联。当创建一个新的Handler时,默认情况下,它将关联到创建它的这个线程和该线程的消息队列。因此,如果通过Handler发布消息的话,消息将只会发送到与它关联的这个消息队列,当然也只能处理该消息队列中的消息。2消息处理对象Handler设计Handler2提示:一个线程可以有多个Handler,但是只能有一个Looper!消息处理对象Handler设计HandlerHandler在创建的时候可以指定Looper,这样通过Handler的sendMessage()方法发送出去的消息就会添加到指定Looper里面的MessageQueue里面去。在不指定Looper的情况下,Handler绑定的是创建它的线程的Looper。如果这个线程的Looper不存在,程序将抛出"Can'tcreatehandlerinsidethreadthathasnotcalledLooper.prepare()"。2消息处理对象HandlerHandler发送消息post(Runnable)postAtTime(Runnable,long)postDelayed(Runnable,long)sendEmptyMessage(int)sendMessage(Message)sendMessageAtTime(Message,long)sendMessageDelayed(Message,long)2Handler可以在任意线程发送消息,这些消息会被添加到关联的MQ上。消息处理对象HandlerHandler发送消息sendMessage()或post()发出的消息都会插在消息队列队尾并按先进先出执行。区别:通过sendMessage()发送的是一个Message对象,会被Handler的handleMessage()方法处理通过post方法发送的是一个Runnable对象,会被封装成Message对象执行。2消息处理对象HandlerHandler发送消息message.target为该Handler对象,这确保了Looper执行到该Message时能找到处理它的Handler,即loop()方法中的代码:msg.target.dispatchMessage(msg);。post发出的Message,其回调为Runnable对象。消息的处理是通过核心方法dispatchMessage(Messagemsg)与钩子方法handleMessage(Messagemsg)完成的。2消息处理对象HandlerHandler处理消息核心方法dispatchMessage(Messagemsg)handleMessage(Messagemsg)2Handler是在它关联的Looper线程中处理消息的。消息处理对象HandlerHandler处理消息dispatchMessage()方法机制Message里面的Callback,一个实现了Runnable接口的对象,其中run函数做处理工作Handler里面mCallback指向的一个实现了Callback接口的对象,由其handleMessage进行处理

处理消息Handler对象对应的类继承并实现了其中handleMessage函数,通过这个实现的handleMessage函数处理消息。2消息处理对象HandlerHandler更新UI流程在Activity中创建Handler并将其引用传递给工作线程,工作线程执行完任务后使用Handler发送消息通知Activity更新UI。2消息处理对象Message和MessageQueueMessageMessage是一个Parcelable对象。Message是线程之间传递信息的载体,包含了对消息的描述和任意的数据对象。Message中包含了两个额外的int字段(Message.arg1和Message.arg2)和一个Object字段,并通过Message.what来标识信息,以便用不同方式处理Message。虽然Message的构造方法是public的,但是最好是使用Message.obtain()或Handler.obtainMessage()方法来获取Message对象,因为Message的实现中包含了回收再利用的机制,可以提高效率。2消息处理对象Message和MessageQueueMessageQueueMessageQueue是用来容纳Message队列的,其中的Message是由Looper来分发的。Message不能直接添加到MessageQueue中,而是要通过与Looper关联的Handler去添加。消息队列通常附属于某一个创建它的线程,可以通过Looper.myQueue()得到当前线程的消息队列。如果没有消息队列对象则会抛出空指针异常。Android在第一次启动程序时会默认会为UIThread创建一个关联的消息队列,用来管理程序的一些上层组件。可以在自己的子线程中创建Handler与UIThread通讯。也就是说程序一启动UI线程也就是主线程就会有一个消息队列,而如果自己另外开启的一个子线程就不会有MessageQueue对象。2异步加载图像示例在UI线程中定义一个Handler在PhotoManager工具类的构造方法里定义Handler稍后在这个Handler里重写handleMessage()方法。当这个Handler接收到由另外一个线程管理的Handler发送过来的新消息时,Android系统会自动调用这个方法,而所有线程对应的Handler都会收到相同信息。3异步加载图像示例把数据从一个任务中转移到UI线程在任务对象中存储数据定义一个Runnable,它运行在一个编码了一个Bitmap且存储这个Bitmap到父类PhotoTask对象里的后台线程。3异步加载图像示例把数据从一个任务中转移到UI线程在后台编码PhotoTask是下一个层次更高的对象,它包含将要展示数据的编码数据和View对象的引用。它会收到一个来自PhotoDecodeRunnable的状态码,并把这个状态码单独传递到一个包含线程池和Handler实例的对象。3异步加载图像示例转移数据到UI处理状态

PhotoManager对象收到了一个状态码和一个PhotoTask对象的handler。因为状态码是TASK_COMPLETE,所以创建一

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论