1、这里理解这三者的关系:有一个消息队列MessageQueue,我们handler要做的工作就是把一个Message对象放入到这个消息队列,并负责处理从消息队列中拿出Message;Looper负责遍历和拿取消息队列内的消息给handler。
a) Handler
i. 构造函数里参入(Looper对象,[Callable对象])
1. 构造Handler的时候可以指定一个Looper对象,如果不指定则利用当前线程的Looper创建。
2. 一个handler可以设置一个callback
3. 如果设置了Callable对象,则凡是通过这个handler发送的消息,都有callback处理,相当于一个总的集中处理
4. 如果发送的Message本身有Callable对象,就会让Message的Callable对象优先处理
ii. 将Message的target设定成自己(目的是为了在处理消息环节,Message能找到正确的Handler),再将这个Message纳入到消息队列中。
1. SendMessage
2. sendMessageDelayed
3. sendMessageAtTime
iii. Handler与线程如何关联
1. 主线程(UI线程)里:如果创建Handler时不传入Looper对象,那么将直接使用主线程(UI线程)的Looper对象(系统已经帮我们创建了)
2. 其它线程里:如果创建Handler时不传入Looper对象,那么,这个Handler将不能接收处理消息。
a) 是不是可以这么理解:子线程里是不会自动创建Looper的,而Handler的空构造函数里调用Looper.myLooper()来获取,这个时候会报错,必须在new Handler()之前先在线程里构造Looper,调用静态方法Looper.prepare()
iv. 需要时刻关心Handler在哪个线程里创建的
b) Looper对象介绍
i. 构造函数为私有,通过prepare()这个函数为我们提供了初始化Looper对象的功能
ii. 系统就会在ThreadLocal内添加一个Looper对象
1. 一个线程只能有一个Looper,若超出一个,则会抛出异常
2. thread local storage(TLS)线程本地存储功能的封装
3. 一个线程内有一个内部存储空间,这样的话我把线程相关的东西就存储到
iii. 调用Looper.loop()这个方法后,Looper才真正的开始工作,在这个函数里循环遍历获取Looper里的消息来执行
1. 从消息队列中得到一个消息后,会调用message的target的dispatchMesage函数
2. 如果msg本身设置了callback,则直接交给这个callback处理
3. 否则,如果该handler的callback有的话,则交给这个callback处理了
4. 否则,由handler得handleMessage执行,但是基类什么事情都不干
iv. 每一个Looper都有一个消息队列,并且这个消息队列作为Looper的一个成员属性
v. 这个消息队列中发送消息
1. 调用looper的static函数myQueue可以获得消息队列,这样你就可用自己往里边插入消息了
2. 利用Handler
c) MessageQueue
i. 消息队列,用来存放Handler发送过来的消息,并按照FIFO规则执行。
1. 将Message以链表的方式串联起来(不是存储起来),等待Looper的抽取