在 ActivityThread 的主程序启动的时候,我们发现 main 方法里面有个 Looper 的 loop() 方法,查看源码会发现里面是个死循环;这样保证应用程序一直在执行;
loop() 源码
public static void loop() {
final Looper me = myLooper();
// 省略一些代码.......
for (;;) {
// 1. 从消息队列里面拿出一个消息
Message msg = queue.next(); // might block
// 2. 让消息的 target 处理(分发)消息
msg.target.dispatchMessage(msg);
if (logging != null) {
logging.println("<<<<< Finished to " + msg.target + " " + msg.callback);
}
// 省略一些代码.......
// 3.处理完后回收
msg.recycle();
}
}从代码上理解,就这3步;
- 取出消息
- 处理消息 (这里注意 target 是 Handler)
- 回收消息
从上面3点可以得出几个结论;
- 肯定有地方去添加消息队列 queue;
- 队列里面的元素是 Message;
- 每个 Message 应该有个 Handler;
把消息添加到队列
android.os.MessageQueue#enqueueMessage
// 加入队列的操作
boolean enqueueMessage(Message msg, long when) {
if (msg.target == null) {
throw new IllegalArgumentException("Message must have a target.");
}
if (msg.isInUse()) {
throw new IllegalStateException(msg + " This message is already in use.");
}
// 省略一些代码.......
}上面代码可以看出,每个Message必须要有 target (handler类型);且不能被用过;那说明时候被添加呢?在来看一段常用的代码;
// 这是一段 hanlder 发送消息的代码
myHandler.sendMessage(message);
...........
.............
// 以上是一段 Handler 发送消息的代码,最终都会到达 Handler 的
private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
// 这个地方把 handler 放进 Message 中
msg.target = this;
if (mAsynchronous) {
msg.setAsynchronous(true);
}
// 这个地方把队列放进去
return queue.enqueueMessage(msg, uptimeMillis);
}结论和总结
当一个 App 启动的时候默认会执行 ActivityThread 的 main 方法;生成应用程序的第一个线程,且创建了一个 Loop, 并执行了 loop() 方法;根据这个 loop 的特性,这个线程就一只执行下去。这个 loop() 的主要作用就是
- 取出消息;2. 处理消息 ;3. 回收消息;这样程序就只要等待一些消息过来然后处理就好了;所以理论上来说
1 个 app 对应一个 ActivityThread
1 个 ActivityThread 对应一个 Loop
1 个 Loop 对应一个消息队列(MessageQueue)
1 个 MessageQueue 对应多个 Message
1 个 Message 必须有1个 handler其实 Message 是个链表,它有 next 的属性;先简单认为是个队列吧。
从上面结论可以看出,如果 MessageQueue 里面的 Message 如果不及时处理,那么会有一些问题;
- 如果队列中有一个 Message 处理时间很长,那么就会影响到后面的 Message 的处理,比如后面都是一些界面刷新操作;那么很有可能不及时了
- 如果被阻塞的 Message 的 Handler 有对大对象的引用(Context, Activity, Fragment, View), 那么很有可能会出现内存泄露;