在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中。
Message与Handler是成对出现的,Message是消息,而Handler是消息要完成任务的对象。
消息是Message的一个实例,在实现一个消息时,要同时实现Message类的一些实例变量,
Handler是完成消息或消息指定任务的对象,Handler不只是完成消息的目标或对象,也是建立和发布消息(Message)的接口。
(图来源于Android权威指南)
在看看下面这个图,
(图来源于Android权威指南)
从上面这个图中,能够看出,有多个Handler与一个Looper相关联,这说明一个Handler的message与另外一个Handler的message放于同一个消息队列。
1. 使用Handler.obtainMessage(...)方法会从公共循环消息队列中,获取message。
2. 使用Handler.sendToTarget()方法,会方法消息发送给与message相关联的Handler。而Handler会将message放于Looper的消息队列尾部。
3. Looper在消息队列中,获取到特定的消息后,将其发送给消息目标(与之相关联的Handler)去处理。消息通常在Handler(消息目标)的handlerMessage(...)实现方法处理消息指定要完成的任务。通常,要继承Handler基类,覆盖handlerMessage()方法。
Handler类的一个实例,能够做为函数参数,传递给其它子线程。
主线程拥有一个Handler和Looper消息循环,在线程中,主线程上建立一个Handler,会自动与主线程的Looper相关联。将主线程建立的Handler传递给另外一个子线程,传递出去的Handler始终会与建立它的线程的Looper保持联系。所以,任何已传出的Handler负责处理的消息,都将在主线程的消息队列中处理。
那么,就能够经过这种方式,在子线程中,去更新主线程的事件,数据,或者UI。
在主线程中不用建立Looper是由于App启动时,建立主线程中默认建立了Looper,而且一个线程中,只能有一个Looper。存在多个系统会报错。
Looper为何不会堵塞主线程,提示ANR(application not responding)?
由于,主线程中的Activity和全部事件都是经过Looper执行的。Looper有一个消息队列,在不断的接收事件消息和执行事件。此中的堵塞是指Looper循环不被堵塞,而非Looper堵塞线程。