消息传递机制的具体实现过程(分析源码之后的总结)
2016-09-19 20:24
441 查看
1,首先得知道有几大类:
a,Message
b,Handler
c,Looper
d,MessageQueue
2,先创建Message对象和Handler对象.如果Handler是在主线程创建的,那么主线程(也就是ActivityThread,俗称UI线程)会在main方法中默认初始化Looper对(MainLooper)去开启消息循环,类似于Looper.prepare();如果是在子线程创建的,那么需要手动调用Looper.prepare(),并且Looper.loop,因为如果没有创建Looper对象,而是直接new Handler(),底层先判断get()方法能否得到当前线程的Looper,如果没有就会抛异常:Can’t
create handler inside thread that has not called Looper.prepare(),所以需要手动调用.调用的过程其实就是底层进行了set()和get()方法,将currentThread(当前进程)的Looper对象和handler对象绑定在一起. 那么 Handler 内部如何获取到当前线程的 Looper 呢? 这就要使用 ThreadLocal 了,ThreadLocal可以在不同的线程中互不干扰地存储并提供数据,通过 ThreadLocal 可以轻松获取每个线程的
Looper。当然需要注意的是,线程是默认没有 Looper 的,如果需要使用 Handler 就必须为线程创建 Looper。所以looper存在于ThreadLocal里面.而looper在什么线程,那么与其绑定的handler处理消息就在什么线程.如果是MainLooper,就能实现更新UI的操作.
3,Looper在创建的时候,构造方法里会初始化MessageQueue,一个Looper对应一个MessageQueue.
4,所有的类初始化完毕,然后handler.sendMessage(msg)发送消息,方法会执行到sendMessageAtTime()这里.此时的msg绑定了when(消息处理的时间),和msg.Target = this(handler将自身的引用绑定在了msg上,是为了在处理多个消息时,能够区分该消息是来自哪个handler),随后通过queue.enqueueMessage()将消息msg放入MessageQueue队列中(利用时间when进行排序,并按先进先出的方式执行,如果没有设置时间,则默认时间为零),虽然叫消息队列,但是它的内部存储结构并不是真正的队列,
而是采用单链表的数据结构来存储消息列表;
5,由于 MessageQueue 只是一个消息的存储单元,它不能去处理消息,而 Looper 就填补了这个功能, Looper 会以无限循环的形式对MessageQueue轮询,去处理消息,如果有消息的话就按顺序依次处理消息,否则就一直等待着(处于阻塞状态);在处理消息的时候,会调用handler的dispatchMessage()方法,最终执行handler.handleMessage(),在该方法里实现处理消息的逻辑(比如更新UI的操作).消息传递就此结束.
a,Message
b,Handler
c,Looper
d,MessageQueue
2,先创建Message对象和Handler对象.如果Handler是在主线程创建的,那么主线程(也就是ActivityThread,俗称UI线程)会在main方法中默认初始化Looper对(MainLooper)去开启消息循环,类似于Looper.prepare();如果是在子线程创建的,那么需要手动调用Looper.prepare(),并且Looper.loop,因为如果没有创建Looper对象,而是直接new Handler(),底层先判断get()方法能否得到当前线程的Looper,如果没有就会抛异常:Can’t
create handler inside thread that has not called Looper.prepare(),所以需要手动调用.调用的过程其实就是底层进行了set()和get()方法,将currentThread(当前进程)的Looper对象和handler对象绑定在一起. 那么 Handler 内部如何获取到当前线程的 Looper 呢? 这就要使用 ThreadLocal 了,ThreadLocal可以在不同的线程中互不干扰地存储并提供数据,通过 ThreadLocal 可以轻松获取每个线程的
Looper。当然需要注意的是,线程是默认没有 Looper 的,如果需要使用 Handler 就必须为线程创建 Looper。所以looper存在于ThreadLocal里面.而looper在什么线程,那么与其绑定的handler处理消息就在什么线程.如果是MainLooper,就能实现更新UI的操作.
3,Looper在创建的时候,构造方法里会初始化MessageQueue,一个Looper对应一个MessageQueue.
4,所有的类初始化完毕,然后handler.sendMessage(msg)发送消息,方法会执行到sendMessageAtTime()这里.此时的msg绑定了when(消息处理的时间),和msg.Target = this(handler将自身的引用绑定在了msg上,是为了在处理多个消息时,能够区分该消息是来自哪个handler),随后通过queue.enqueueMessage()将消息msg放入MessageQueue队列中(利用时间when进行排序,并按先进先出的方式执行,如果没有设置时间,则默认时间为零),虽然叫消息队列,但是它的内部存储结构并不是真正的队列,
而是采用单链表的数据结构来存储消息列表;
5,由于 MessageQueue 只是一个消息的存储单元,它不能去处理消息,而 Looper 就填补了这个功能, Looper 会以无限循环的形式对MessageQueue轮询,去处理消息,如果有消息的话就按顺序依次处理消息,否则就一直等待着(处于阻塞状态);在处理消息的时候,会调用handler的dispatchMessage()方法,最终执行handler.handleMessage(),在该方法里实现处理消息的逻辑(比如更新UI的操作).消息传递就此结束.
相关文章推荐
- OpenStack建立实例完整过程源码详细分析(13)----依据AMQP通信架构实现消息发送机制解析之二
- OpenStack建立实例完整过程源码详细分析(15)----依据AMQP通信架构实现消息接收机制解析之二
- OpenStack建立实例完整过程源码详细分析(12)----依据AMQP通信架构实现消息发送机制解析之一
- OpenStack建立实例完整过程源码详细分析(14)----依据AMQP通信架构实现消息接收机制解析之一
- Android异步消息传递机制源码分析
- 源码分析RocketMQ消息过滤机制上篇-----消息消费服务端过滤与TAG模式过滤实现
- 消息机制实现_源码分析
- Ogre源码剖析:如何实现低耦合的类间消息传递机制
- Ogre源码剖析:如何实现低耦合的类间消息传递机制
- Openck_Swift源码分析——增加、删除设备时算法具体的实现过程
- 从源码分析Android中Handler的消息传递机制
- Android消息处理机制源码分析(一):整体过程
- 源码分析Android消息传递机制
- Android消息处理机制源码分析(二):本地实现
- MVVMLight源码分析之消息机制和ViewModelBase
- winform 下实现消息传递机制
- 消息中间件 activeMQ的源码分析 之 TCP通讯机制
- 如何实现基于消息安全验证机制下的username身份验证过程
- UCGUI 消息机制实现分析
- Ogre是如何实现低耦合的类间消息传递机制的?