Android系统中,Java的应用程序和其他的系统相同,都是靠消息驱动工作的,大致的工作原理是:
有一个消息队列,可以往这个消息队列中投递消息。
有一个消息循环,不断从消息队列中取出消息,然后处理。
在Android系统中,这些工作主要是由Looper和Handler类来实现。
Looper类,用于封装消息循环,并且有一个消息队列。
Hanlder类,有点像辅助类,它封装消息投递,消息处理等接口。
Looper类分析
在线程中有一个线程局部变量类,调用Looper的prepare()方法,会在线程的局部变量类中设置一个Looper对象。这个Looper对象就保存在这个调用线程的TLV中。而Looper对象内部封装了一个消息队列。也就是说,prepare函数通过ThreadLocal机制,巧妙地把Looper和调用线程关联在一起了。
Looper循环
Looper类有一个myLooper()方法,调用这个方法,可以返回调用线程的线程局部
变量,也就是存储在其中的Looper对象 。
loop()函数内部的处理过程为:
1. 调用myLooper方法返回保存在调用线程TLV中的Looper对象。
2. 取出这个Looper的消息队列。
3. 处理消息,Message对象中有一个target,它是Handler类型。
4. 如果target为空,则表示需要退出消息循环,否则,调用该消息的Handler,交给它的dispatchMessage函数处理。
简单理解,Looper的作用是:
1. 封装一个消息队列。
2. Looper的prepare函数把这个Looper和调用prepare的线程(也就是最终的处理线程)绑定在一起了。
3. 处理线程调用loop函数,处理来自消息队列的消息。
当事件源向这个Looper发送消息的时候,其实是把消息加入到这个Looper的消息队列里面。那么该消息就将和Looper绑定的处理线程来处理。
Looper,Message和Handler的关系
Looper中有一个Message队列,里面存储的是一个个待处理的Message。
Message中有一个Handler,这个Handler是用来处理Message的。
Handler分析
Handler中的消息队列,实际上就是某个Looper中的消息队列。
如果不知道Handler,怎么往Looper的消息队列中插入消息。
1. 调用Looper的myQueue,它将返回一个消息队列对象MessageQueue。
2. 构造一个Message,填充它的成员,尤其是target变量。
3. 调用MessageQueue的enqueueMessage,将消息插入消息队列。
Handler和Message
Handler提供了一系列函数帮助我们完成创建消息和插入消息队列的工作。
用Handler处理消息时,Handler把Message的target设为自己,是因为Handler除了封装消息添加等功能外还封装了消息处理的接口。
Handler的消息处理
往Looper的消息队列里添加一个消息后,按照Looper的处理机制,它在获得消息后会调用target的dispatchMessage函数,再把这个消息派发给Handler处理。
dispatchMessage定义了一套消息处理的优先级机制
1. Message如果自带了callback处理,则交给callback处理。
2. Handler如果设置了全局的mCallback,则交给mCallback处理。
如果上述都没有,则该消息会被交给Handler子类实现的handleMessage来处理。当然,这需要从Handler派生并重载handleMessage函数。
Looper和Handler的同步关系
在一个线程中创建Looper,在另一个线程中去取这个Looper的值,可能Looper还没来得及创建,这个时候去取,则会得到null值。
这个问题可以通过使用HandlerThread来解决。