Android之Handler基础篇

1、Handler是什么?

  在Android开发中,使用消息队列(message)完成线程间通讯。而使用消息队列的线程就是消息循环(message looper)。消息循环不断的检查消息队列,是否有新消息。消息循环是由一个线程和一个looper组成;looper对象管理着线程的消息队列。app

  Android的主线程也是一个消息循环,也具备一个Looper,主线程全部的任务都是由looper完成。消息循环是由一个线程和一个looper组成,looper对象管理着线程的消息队列;所以,looper不断的从消息队列中抓取消息,而后完成消息指定的任务。函数

  PS: 线程默认状况下,是没有消息循环(Looper)的,在Android中,只有主线程默认就是Looper(消息循环)。在新建立的线程中,使用Looper,要先建立一个Looper才行。oop

  从下面图中了解一下Runnable、Message、MessageQueue、Looper、Handler含义:spa

                (此图来自于其它书籍资料)线程

  将这此含义揉合在一块儿就是一个消息从发出到执行的整个过程:3d

              (此图来自于其它书籍资料)对象

  从上面这两个图中,咱们能够了解到:blog

  1. Runnable和Message压入到MessageQueue中,造成一个消息集合。继承

  2. Looper在不断的循环,不停的在作某一件事,好比:上图中Looper在不停的从MessageQueue中拿出Item,再传递给Handler执行。接口

  3. Handler在不断的去作某一具体的事情,好比:Handler收到一个消息,去解析一个后台返回的数据,再将其更新到UI上。

  从上面来看,Handler和Thread从表像上看确实没有直接的关系,可是由于:

  1.  每一个Thread只能对应一个Looper;

  2. 每一个Looper只能对应一个MessageQueue;

  3. 每一个MessageQueue有N个Message;

  4. 每一个Message最多指定一个Handler来处理;

  由此,能够推出Thread和Handler是一对多的关系。而Handler有两方面做用:

  1. 处理Message,做为Message处理者。

  2. 负责将Message压入MessageQueue中。 

2、Message与Handler

  Message与Handler是成对出现的,Message是消息,而Handler是消息要完成任务的对象。

  消息是Message的一个实例,在实现一个消息时,要同时实现Message类的一些实例变量,

    • what: 用户定义的Int类型消息代码,用来描述消息。
    • obj: 随消息一块儿发送的用户指定的对象,即消息传递的数据。
    • target:完成消息指定任务的目标,即用来完成消息指定任务的对象。

  Handler是完成消息或消息指定任务的对象,Handler不只是完成消息的目标或对象,也是建立和发布消息(Message)的接口。

                 (图来源于Android权威指南)

  • Looper拥有message的消息队列,因此,message必须在Looper上发布或读取。
  • 一个Handler仅一个Looper相关联,一个Message也仅与一个目标Handler(message目标)相关联。而Looper拥有消息的整个队列。

  在看看下面这个图,

 

 

              (图来源于Android权威指南)

 

从上面这个图中,能够看出,有多个Handler与一个Looper相关联,这说明一个Handler的message与另外一个Handler的message放于同一个消息队列。

 3、Handler使用

  1. 使用Handler.obtainMessage(...)方法会从公共循环消息队列中,获取message。

  2. 使用Handler.sendToTarget()方法,会方法消息发送给与message相关联的Handler。而Handler会将message放于Looper的消息队列尾部。

  3. Looper在消息队列中,获取到特定的消息后,将其发送给消息目标(与之相关联的Handler)去处理。消息通常在Handler(消息目标)的handlerMessage(...)实现方法处理消息指定要完成的任务。通常,要继承Handler基类,覆盖handlerMessage()方法。

 4、传递Handler

  Handler类的一个实例,能够做为函数参数,传递给其它子线程。

  主线程拥有一个Handler和Looper消息循环,在线程中,主线程上建立一个Handler,会自动与主线程的Looper相关联。将主线程建立的Handler传递给另外一个子线程,传递出去的Handler始终会与建立它的线程的Looper保持联系。所以,任何已传出的Handler负责处理的消息,都将在主线程的消息队列中处理。

  那么,就能够经过这种方式,在子线程中,去更新主线程的事件,数据,或者UI。

5、在新线程中,建立Looper(消息循环)

  在主线程中不用建立Looper是由于App启动时,建立主线程中默认建立了Looper,而且一个线程中,只能有一个Looper。存在多个系统会报错。

  Looper为何不会堵塞主线程,提示ANR(application not responding)?

  由于,主线程中的Activity和全部事件都是经过Looper执行的。Looper有一个消息队列,在不断的接收事件消息和执行事件。此中的堵塞是指Looper循环不被堵塞,而非Looper堵塞线程。

相关文章
相关标签/搜索