定义
Android的消息机制主要是指Handler的运行机制,Handler的运行需要底层的MessageQueue和Looper的支撑。
作用
将工作线程中需更新UI的操作信息传递到 UI主线程。
为什么要用 Handler消息传递机制呢
首先我们可以从下两个问题中得到答案:
系统为什么不允许在子线程中访问UI呢?
因为Android的UI控件不是线程安全的,如果在多线程中并发访问可能会导致UI控件处于不可预期的状态
为什么系统不对UI控件的访问加上锁机制呢?
首先加上锁机制会让UI访问的逻辑变得复杂;其次锁机制会降低UI访问的效率,因为锁机制会阻塞某些线程的执行。
所以:对于开发者来说最简单且高效的方法就是采用单线程模型来处理UI操作,通过Handler切换一下UI访问的执行线程即可。
相关概念
说明:
MessageQueue:它是通过一个<font color="#FF3030">单链表</font>的数据结构来维护消息列表。
Looper.prepare()可为当前线程创建一个Looper
Looper.loop()来开启消息循环
1个线程(Thread)只能绑定 1个循环器(Looper),但可以有多个处理者(Handler)
1个循环器(Looper) 可绑定多个处理者(Handler)
1个处理者(Handler) 只能绑定1个循环器(Looper)
消息机制分析
- ThreadLocal
定义:一个线程内部的数据存储类,通过它可以在指定的线程中存储数据,数据存储以后,只有在指定线程中可以获取到存储的数据,对于其他线程来说则无法获取到数据。
使用场景:
a. 某些数据是以线程为作用域并且不同线程具有不同的数据副本
b. 杂逻辑下的对象传递,比如监听器的传递 - Handler机制的工作流程主要包括4个步骤:
(1)异步通信准备:在主线程中创建处理器对象(Looper
)、消息队列对象(MessageQueue
)、Handler
对象;
(2)消息发送:Handler.sendMessage()
发送消息时,会通过MessageQueue.enqueueMessage()
向MessageQueue
中添加一条消息;
(3)消息循环:通过Looper.loop()
开启循环后,不断轮询调用MessageQueue.next()
;
(4)消息处理:调用目标Handler.dispatchMessage()
去传递消息,目标Handler
收到消息后调用Handler.handlerMessage()
处理消息。
主线程的消息循环
Android的主线程就是ActivityThread,在入口方法main方法中系统会通过Looper.prepareMainLooper()
来创建主线程的Looper以及MessageQueue,并通过Looper.loop()
来开启主线程的消息循环。
消息循环开始了以后,需要一个Handler来和消息队列进行交互,这个Handler就是ActivityThread.H
,它内部定义了一组消息类型,主要包含了四大组件的启动和停止等过程。
ActivityThread通过ApplicationThread和AMS进行进程间通信,AMS以进程间通信的方式完成ActivityThread的请求后会回调ApplicationThread中的Binder方法,然后ApplicationThread会向H发送消息,H收到消息后会将ApplicationThread中的逻辑切换到ActivityThread中去执行,即切换到主线程中去执行,这个过程就是主线程的消息循环模型。