Looper
Looper为消息循环器, 不停的取出MessageQueue中的消息,并把获取的消息分发下去。
是MessageQueue和Handle交互的桥梁。
- 提供prepare()方法
prepare方法中通过sThreadLocal(new Looper())
初始化了Looper, 并在Looper的构造方法中,new MessageQueue()
创建了messageQueue
- loop()
启动循环遍历消息,然后通过dispatchMessage()
把消息分发到Handle中。 - quite()
直接退出looper - quiteSafety()
做一个退出标记,等消息处理完后,再退出
如图:
Looper对象只能创建一次。
子线程中创建Handler失败,就是因为子线程中没有Looper对象导致的。
MessageQueue
MessageQueue是存储的消息队列,内部采用单链表的数据结构。
当消息来临时,如果队列为空,就放入头部中。
反之,按照创建时间进行插入链表中。
- enqueueMessage()
此方法就是存储Message - next()
读取消息
如图:
Handler
handler用来发送和接受消息。
- Handler()
此时会获取Looper、MessageQueue - 发送消息
发送消息分为两种方式。- sendMessage
- post
两者最终调用的方法都是enqueueMessage
- 接受消息
接受消息也分为两个方式。- handleMessage
- handleCallback
发送的方式不同,接受的方式也就不同
如图:
在主线程中,程序会通过Looper.PrepareMainLooper默认创建一个Looper,所以我们在使用时就不需要调用Looper.prepare方法,但是如果在子线程中使用Handle,必须调用Looper.prepare方法,进行创建Looper对象
Looper.PrepareMainLooper方法供系统调用,我们需要调用Looper.prepare方法
ps:子线程调用顺序
ublic class LooperThread extends Thread {
public Handler mHandler;
@Override
public void run() {
//顺序不可颠倒
Looper.prepare();
synchronized (this) {
mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
}
};
}
//顺序不可颠倒
Looper.loop();
notifyAll();
}
Looper、Handler、MessageQueen关系
Handler通过post、sendMessage把消息发送给MessageQueen,MessageQueen通过enqueueMessage方法,把Message存储到MessageQueen中,Looper在prepare()中,关联了一个MessageQueen,Looper在loop()方法中,通过next()把消息取出来,如果为空则阻塞Looper,否则通过dispatchMessage把消息分发到Handler中,Handle根据发送消息方式的不同,调用handleMessage、handleCallback不同的方法。
如图: