我们已经知道Android的消息机制处理主要由Handler、Message、MessageQueue、Looper四个类的实现来完成。那么它们之间的关系是怎样的?
其中,Message是消息主体,它负责存储消息的各种信息,包括发送消息的Handler对象、消息信息、消息标识等。MessageQueue就是消息队列,在其内部以队列的形式维护一组Message(消息)。Handler负责发送和处理消息。Looper负责轮询消息队列。
每个线程都可以并仅可以拥有一个Looper实例,消息队列MessageQueue在Looper的构造函数中被创建并且作为成员变量被保存,也就是说MessageQueue相对于线程也是唯一的。Android应用在启动的时候会默认会为主线程创建一个Looper实例,并借助相关的Handler和Looper里面的MessageQueue完成对Activities、Services、Broadcase Receivers等的管理。而在子线程中,Looper需要通过显式调用Looper. Prepare()方法进行创建。Prepare方法通过ThreadLocal来保证Looper在线程内的唯一性,如果Looper在线程内已经被创建并且尝试再度创建"Only one Looper may be created per thread"异常将被抛出。
Handler在创建的时候可以指定Looper,这样通过Handler的sendMessage()方法发送出去的消息就会添加到指定Looper里面的MessageQueue里面去。在不指定Looper的情况下,Handler绑定的是创建它的线程的Looper。如果这个线程的Looper不存在,程序将抛出"Can’t create handler inside thread that has not called Looper.prepare()"。
整个消息处理的大概流程是:1. 包装Message对象(指定Handler、回调函数和携带数据等);2. 通过Handler的sendMessage()等类似方法将Message发送出去;3. 在Handler的处理方法里面将Message添加到Handler绑定的Looper的MessageQueue;4. Looper的loop()方法通过循环不断从MessageQueue里面提取Message进行处理,并移除处理完毕的Message;5. 通过调用Message绑定的Handler对象的dispatchMessage()方法完成对消息的处理。
在dispatchMessage()方法里,如何处理Message则由用户指定,三个判断,优先级从高到低:1. Message里面的Callback,一个实现了Runnable接口的对象,其中run函数做处理工作;2. Handler里面mCallback指向的一个实现了Callback接口的对象,由其handleMessage进行处理;3. 处理消息Handler对象对应的类继承并实现了其中handleMessage函数,通过这个实现的handleMessage函数处理消息。
一个线程开启循环模式持续监听并依次处理其他线程给它发的消息。
简单的说:一个线程开启一个无限循环模式,不断遍历自己的消息列表,如果有消息就挨个拿出来做处理,如果列表没消息,自己就堵塞(相当于wait,让出cpu资源给其他线程),其他线程如果想让该线程做什么事,就往该线程的消息队列插入消息,该线程会不断从队列里拿出消息做处理。
相关文章
- 02-26如何远程控制我的Android?
- 02-26Android SDK应用无法加载库
- 02-26华为大神花费5个月打造的这份714页学习笔记系列!Android面试题及解析
- 02-26Android Dagger-没有no-args构造函数的模块
- 02-26Android-Dagger 2不生成组件
- 02-26Android注解三大框架Dagger、Hilt和Koin有何不同?
- 02-26android逆向!靠着这份900多页的PDF面试整理,搞懂这些直接来阿里入职
- 02-26《Practical Vim》第十章:复制和粘贴
- 02-26Android Studio编译错误:Error while generating the main dex list
- 02-26Android 调用OpenCV(二)