首先要介绍的是:Message这个类:
Message有三个必要重要的成员变量
1:int what(记录消息的种类)
2:Handler target(记录是谁把Message发送出去的,以后就由谁处理)
3:long when(处理消息的时间)
4:Message next;(当前消息的下个消息)
小结Message成员变量next和when使得消息成为一条链的结构如下图
When决定消息的顺序
下面我们在子线程里面初始化一个Handler对象,并使用他。那么为什么要舍近求远的选择子线程呢?因为主线程默认对Handler做了很多操作,不便于查看,接下里我们通过handler的使用过程来讲解Handler:
1、Looper.prepare();
这个方法必须调用不然就会直接崩溃,并且要先于new Handler之前调用
开始很多人就会有疑问:我在使用Handler的时候并没有调用这个方法啊?为什么他必须要调用,不调用还会报错?这里需要解释的是:一般的人都是在主线程中使用Handler,在主线程中其实也是调用的类似的方法的,接下来我们找到主线程中调用prepare()如下:
ActivityThread.java中的main方法:
public staticfinal void main(String[] args) {
//系统调用Looper.prepare()方法
Looper.prepareMainLooper();
//开启ActivityThread线程,即当前Android应用主线程
ActivityThread thread = new ActivityThread();
thread.attach(false);
//主线程Wile(true)?分发消息
Looper.loop();
}
所以说,在使用Handler之间肯定是要调用prepare这个方法的。那么调用这个方法做了什么操作呢?
new了一个looper对象然后调用了Looper的私有构造函数:
private Looper(boolean quitAllowed) {
mQueue = new MessageQueue(quitAllowed);
mRun = true;
mThread = Thread.currentThread();
}
在构造函数当中,待建了一个MessageQueue对象,将该对象设置给threadLocal通过threadLocal,给当前的线程,绑定了一个looper对象
小结:
1在一个线程当中,Looper.prepare()只能调一次,调用二次会抛异常。
2在主线程当中,此方法由系统调用,我们不用去调,详细代码可见:ActivityThead.java中的main方法
2、创建handler,使用handler发送消息。
Handler的构造函数当中主要干了二件事:
获得当前线程绑定的looper对象
mLooper = Looper.myLooper();
获得looper对象的messageQueue的引用
mQueue = mLooper.mQueue;
小结:其实这个地方和第一步创建Handler对象是一个相反的过程
handler发送信息:所有发送信息的方法,最终还是调用sendMessageAtTime(msg ,when)
在sendMessageAtTime方法中:msg.target
= this; // this就是当前handler,记录谁把消息发送到消息队列里面的,以后就会调用这个Handler把自己发送出去
queue.enqueueMessage(msg, uptimeMillis);
//
queue是MessageQueue如图
首先如果消息队列里面没有消息,或者消息的when小于第一条消息那么,加入的这条消息就会添加到消息队列的第一条,如果消息队列里面存在消息而且消息的when不小于第一条消息,那个这个时候,代码就会进入else里面,这个时候做的第一件事就是声明一个临时变量,然后进入到for(;;){}这个循环体。这个循环体其实就等价于while(true);接下来就是比较消息的when的大小了。然后给消息找到一个合适的位置,并插入。
小结:对象,enqueueMessage()方法,当前message ,加入到消息对列当中
MessageQueue中的代码:
enqueueMessage方法
这个方法将消息加入到消息对列中,在加入之前会通过每个消息的时间进行比较,然后把消息插入到相应的位置,他定义个临时变量
结论:
在MessageQueue当中,所有的message都是以单链的形式保存的,而且按时间从小到大的顺序保存取消息的方法(next())从messageQueue当中取出下一个应该执行的message,如果时间未到,就等待。
3、Looper.loop();
publicstatic void loop() {
final Looper me = myLooper();
final MessageQueue queue = me.mQueue;
for (;;) {//相当于while(true)死循环
//从messageQueue当中取出下一个应该执行的message如果时间未到,就等着
Message msg = queue.next(); // might block
//调用message对应的handler中的dispatchMessage方法,最终执行handleMessage方法
msg.target.dispatchMessage(msg);
}
}
总结:Handler机制里面其实包括了相关的类很多几个比较重要的类如:Handler、Message、Thread、MessageQuen、Loop。
Handler:发送消息和处理消息
Message:消息的信息的载体,记录被处理的时间和由谁处理
Thread:通过ThreadLocal记录每一个线程的MessageQuen
MessageQuen:存放消息的地方
Loop:取消息