Android中Handler机制祥解
1.Handler
什么是handler
1.handler安卓系统里面的一种消息处理机制.
2.handler可以实现异步操作处理.子线程更新UI操作.
handler的关键的类
-
handler(handler里持有looper和MessageQueue)
-
message(想象成一个人)(底层是链表结构)(message里面通过taeget成员变量持有handler的引用)
-
lopper(想象成一个人)(looper在其构造函数里把 MessageQueue创建处理)
-
MessageQueue(可以想象成现实中的一个容器)(一个通过链表模拟的一个消息队列,每次把一个消息入队的时候从队头开始,一个一个比较然后插入到合适的位置)
对象A: H
对象B : L
一张记录信息的文件:M
一个容器:MQ
handler发送消息,然后lopper检测MessageQueue队列中有没有这条消息,有的话去处理
发送消息然后lopper收到消息去
为什么主线程不会被阻塞?
有系统唤醒他handler也是一样主线程handler发送消息,然后lopper检测MessageQueue队列中有没有这条消息,有的话去处理
handler有几种发送消息的方式
post(Runnable) postAtTime(Runnable,long) postDelayed(Runnable long) sendEmptyMessage(int) sendMessage(Message) sendMessageAtTime(Message,long) sendMessageDelayed(Message,long) 以上post类方法允许你排列一个Runnable对象到主线程队列中, sendMessage类方法, 允许你安排一个带数据的Message对象到队列中,等待更新. 使用 Handler 在子线程中向 UI 线程发送一个消息进行 UI 的更新 创建一个 Message, Message msg = new Message(); msg.arg1 = 88; handler.sendMessage(msg); msg.obj = xxx; 可以传递一个对象 当然不一定要用 new 一个 Message,也可以复用系统的 message 对象 Message msg = handler.obtainMessage();
面试题:
handler延时消息是怎么执行的
当我使用sendEmptyMessageDelayed的时候,源码依次的调用顺序是;
sendEmptyMessageDelayed(int what, long delayMillis) —>
sendMessageDelayed(Message msg, long delayMillis) —>
sendMessageAtTime(Message msg, long uptimeMillis) —>
Threadlocal:
ThreadLocal就是用来在类中声明的一个标记,然后通过这个标记就根据不同Thread对象存取值。
上面字写的比较难看但下面给大家奉上总结??:
- 如果我sendEmptyMessageDelayed发送了消息A,延时为500ms,这时消息进入队列,触发了nativePollOnce,Looper阻塞,等待下一个消息,或者是Delayed时间结束,自动唤醒;
- 在1的前提下,紧接着又sendEmptyMessage了消息B,消息进入队列,但这时A的阻塞时间还没有到,于是把B插入到A的前面,然后调用nativeWake()方法唤醒线程
- 唤醒之后,会重新都取队列,这是B在A前面,有不需要等待,于是直接返回给Looper
- Looper处理完该消息后,会再次调用next()方法,如果发现now大于msg.when则返回A消息,否则计算下一次该等待的时间
网上看到的总结:
1. Message
消息,理解为线程间通讯的数据单元。例如后台线程在处理数据完毕后需要更新UI,则可发送一条包含更新信息的Message给UI线程。
2. Message Queue
消息队列,用来存放通过Handler发布的消息,按照先进先出执行。
3. Handler
Handler是Message的主要处理者,负责将Message添加到消息队列以及对消息队列中的Message进行处理。
4. Looper
循环器,扮演Message Queue和Handler之间桥梁的角色,循环取出Message Queue里面的Message,并交付给相应的Handler进行处理。
5. 线程
UI thread 通常就是main thread,而Android启动程序时会替它建立一个Message Queue。每一个线程里可含有一个Looper对象以及一个MessageQueue数据结构。