刚开始学安卓,零零散散把平时学到的一些知识点总结了一下,希望能有些帮助吧。本篇文章主要总结了Android中的Handler消息处理机制,主要参考了李刚的《疯狂Android讲义》和任玉刚的《Android开发艺术探索》。个人水平有限,如果有不对的地方,欢迎大家批评指正。好啦,下面开始正文。

我们知道,Android不允许在主线程中进行耗时操作,因此例如访问网络、读取文件等耗时的I/O操作都需要在子线程中进行。当耗时操作完成之后,我们很可能需要在UI上作出一些改变,但是由于Android开发规范的限制,我们不能在子线程中访问UI组件,否则会触发程序异常。那么我们在子线程中操作的结果如何反映到主线程的UI界面上呢?这时候我们就可以使用Handler来进行处理。

Handler通过传递和处理Message消息,实现线程之间的切换,同时需要底层的MessageQueue来存储Message消息,通过Looper无限循环来查找是否有新的消息。下面我们就来看看这几个对象的主要功能,还有Handler消息处理机制的工作原理。

Message:消息

主要功能

  • 由Handler发送并且处理的对象,主要包含消息ID、以及处理的数据等,由MessageQueue统一列队,最终由Handler处理。

常用的属性和方法

  • Message.what属性,为Message添加ID
  • Message.target,发送消息的Handler对象
  • Message.setData(Bundle bundle)方法,通过Bundle传递数据

Handler

主要功能

  • 负责Message消息的发送和处理。
  • Handler的正常工作需要依赖于Looper,因此在创建Handler的线程中,必须先创建Looper对象,否则将会出现异常。
  • 在主UI线程中,系统已经初始化一个Looper对象,可以直接创建并使用Handler。但是在自己开启的子线程中,必须创建Looper对象才可以正常使用Handler。

常用方法

发送消息

  • sendEmptyMessage(int what),发送空消息
  • sendEmptyMessageDelayed(int what, long delayMillis),延迟发送的空消息
  • sendMessage(Message msg),发送消息
  • sendMessageDelayed(Message msg, long delayMillis),延迟发送的消息

处理消息

  • handleMessage(Message msg),对特定的Message进行处理

判断是否有消息

  • hasMessage(int what)
  • hasMessage(int what,Object object)

MessageQueue消息队列

主要功能

  • 用来存放Handler发送过来的消息,并按照FIFO(先入先出)的规则执行。当然,存放Message并非实际意义的保存,而是将Message以链表的方式串联起来的,等Looper的抽取。

常用方法

  • enqueueMessage(Message msg,long when),往消息队里中插入一条消息,按照发送的时间when排列
  • next(),读取消息,通过无限循环的方式,读取消息队列中的内容,如果有消息,则返回该消息并从消息队列中删除该消息,如果没有消息,则一直阻塞在那里。

Looper

主要功能

  • 不断从MessageQueue中抽取Message并交给Handler处理。
  • 一个线程中的MessageQueue需要一个Looper进行管理。Looper是当前线程创建的时候产生的(UI Thread即主线程是系统帮忙创建的Looper,而如果在子线程中,需要手动在创建线程后立即创建Looper[调用Looper.prepare()方法])。也就是说,会在当前线程上绑定一个Looper对象。

常用方法

  • Looper.prepare(),创建Looper。创建Looper时,会在其内部创建一个MessageQueue对象。
  • Looper.loop(),启动Looper。会调用MessageQueue中的next()方法,无限循环读取消息。如果有新消息,则将next()方法返回的Message对象交给Handler进行处理。没有没有新消息,next()方法阻塞,loop方法也阻塞。如果next()返回null,则跳出loop()方法,结束循环。
  • Looper.quit()或者Looper.quitSafely(),退出Looper。会调用MessageQueue的对应方法,使next()返回null。

工作流程

  1. 创建Looper对象:因为Handler的使用需要依赖于Looper,因此需要现在需要使用Handler的线程中通过Looper.prepare()方法创建Looper对象,并且通过Looper.loop()开启循环。对于主线程还有HandlerThread,这两种线程里面都已经初始化了Looper对象,并且loop方法也已经开启,因此在这两种线程中可以直接创建Handler对象,否则必须先创建Looper。

  2. 在初始化Looper的线程中创建Handler对象。在其构造函数中,获取到Looper对象、MessageQueue对象(从Looper中获取的),并将handler作为message的标签设置到msg.target上

  3. 发送消息:通过Handler的sendMessage()方法发送消息。sendMessage(Message msg)最终都会调用MessageQueue的enqueueMessage()方法将消息插入到消息队列中,依据传入的时间进行消息入列。

  4. 轮询消息:在Looper.loop()方法中,获取到MessageQueue对象后,会调用MessageQueue的next()方法从中取出消息(Message msg = queue.next())。Loop()方法是无限循环的,而next()方法也是无限循环的。如果没有没有新消息,next()方法阻塞,loop方法也阻塞。如果有新消息,则获取next()方法返回的Message对象,调用msg.target.dispatchMessage(msg)方法交给Handler进行处理。如果next()返回null,则跳出loop()方法,结束循环。

  5. dispatchMessage(msg)方法的执行过程:先判断msg的callback是否为空,不为空就调用Message的handleCallback()方法来处理;再判断mCallback是否为空,不为空就调用mCallback的handleMessage()方法来处理;最后调用Handler的handleMessage()方法来处理

6.结束Looper对象。因为Looper是通过无限循环的方式来判断消息队列中是否有新消息,当程序处理完成之后,最好调用Looper.quit()或者Looper.quitSafely()方法退出Looper,避免浪费系统资源。

主线程Handler的消息处理机制原理:

  • 在创建Activity之前,当系统启动的时候,先加载ActivityThread这个类,在这个类中的main函数,调用了Looper.prepareMainLooper()方法创建主线程的Looper以及MessageQueue对象,并通过Looper的loop()方法开启主线程的消息循环。
  • ActivityThread的Handler就是ActivityThread.H,其内部定义了一组消息类型,主要包含四大组件的启动和停止过程。
  • 系统的某些组件或者其他的一些活动等发送了系统级别的消息,这个时候主线程中的Looper就可以进行轮询消息,并调用msg.target.dispatchMessage(msg)(msg.target即为handler)进行分发消息,并通过handler的handleMessage方法进行处理;所以会优于我们自己创建的handler中的消息而处理系统消息。

更多相关文章

  1. 【转】Android最佳性能实践(三)——高性能编码优化
  2. 全面了解Android开发规范
  3. Android(安卓)XML解析之SAX解析 简单示例讲解
  4. Android(安卓)EventBus库的使用
  5. [置顶] Android(安卓)View(二)-View的scrollTo()以及scrollBy()
  6. Android(安卓)微信支付成功后返回App没有走回调
  7. Android(安卓)IntentService的使用和源码分析
  8. Android使用C/C++来保存密钥
  9. 百度地图(1)

随机推荐

  1. python获取外网IP并发邮件
  2. 在Python中,如何在使用WPF的程序中自动控
  3. CentOS下实现Flask + Virtualenv + uWSGI
  4. PySide-QtWebKit: CSS font-family没有效
  5. python学习笔记10(函数一): 函数使用、调用
  6. python爬取csdn的博客内容
  7. 利用python Pandas进行数据预处理
  8. python 带正则的search 模块
  9. Python基础1--数据类型
  10. 第四章 Python 对象