概述
通过下边的代码分析源码
// 根据这个实例代码分析下边源码
new Thread(new Runnable() {
@Override
public void run() {
Looper.prepare();
// 子线程中创建 handler对象
handler2 = new Handler() ;
Looper.loop();
}
}).start();
1. Looper源码
Looper的构造方法:
/**
* Looper 的构造方法
*/
private Looper(boolean quitAllowed) {
// 在构造方法中 创建 MessageQueue消息队列对象
mQueue = new MessageQueue(quitAllowed);
mThread = Thread.currentThread();
}
// ThreadLocal作用:在 一个线程中存储一个变量,这里存储的是 looper对象
static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();
/**
* Looper.prepare()方法
*/
private static void prepare(boolean quitAllowed) {
// 从sThreadLocal对象中获取 looper对象,如果不为null,就抛异常,说明 Looper.prepare()
// 只能调用1次,保证1个线程中只有一个 looper对象
if (sThreadLocal.get() != null) {
throw new RuntimeException("Only one Looper may be created per thread");
}
// 第一次调用 Looper.prepare(),就把 looper对象存储到 sThreadLocal对象中
sThreadLocal.set(new Looper(quitAllowed));
}
/**
* Looper.loop()方法
*/
public static void loop() {
// 从 ThreadLocal 中 获取looper对象
final Looper me = myLooper();
// 如果 looper 对象为空,就抛异常,因为 looper 对象是在 Looper.prepare() 方法中
// 通过 sThreadLocal.set(new Looper(quitAllowed)) 添加到 ThreadLocal 中的 ,
// 先执行 Looper.prepare(),然后执行 Looper.loop()
if (me == null) {
throw new RuntimeException("No Looper; Looper.prepare() wasn't
called on this thread.");
}
// 从 looper 中 取出 消息队列 MessageQueue,因为 MessageQueue对象 是在 Looper的构造方法
// new出来的
final MessageQueue queue = me.mQueue;
// 从这里开始,就进入一个死循环
for (;;) {
// 从消息队列 中取出一条消息 msg
Message msg = queue.next(); // might block
// 如果 msg为null,消息队列进入阻塞状态
if (msg == null) {
// No message indicates that the message queue is quitting.
return;
}
try {
// msg.target就是handler,如果 消息队列中有消息 msg,就把 msg交给
// handler.dispatchMessage处理
msg.target.dispatchMessage(msg);
} finally {
//...
}
// 释放消息占用的资源
msg.recycleUnchecked();
}
}
/**
* 从ThreadLocal中获取 looper,然后返回 looper对象
*/
public static @Nullable Looper myLooper() {
return sThreadLocal.get();
}
结论:
1>:由下可知:一个线程只有1个looper对象;
if (sThreadLocal.get() != null) {
throw new RuntimeException("Only one Looper may be created per thread");
}
由下可知:一个looper对象 只有1个 消息队列MessageQueue
private Looper(boolean quitAllowed) {
// 在构造方法中 创建 MessageQueue消息队列对象
mQueue = new MessageQueue(quitAllowed);
mThread = Thread.currentThread();
}
2>:对于 loop() 方法:不断的从 消息队列MessageQueue 中取出 消息msg,如果msg为null,则消息队列阻塞;如果有消息msg就交给 handler.dispatchMessage(msg)处理;
2. Handler源码
首先看Handler的构造方法:
public Handler() {
this(null, false);
}
public Handler(Callback callback, boolean async) {
// ... 省略一些代码
// 从 ThreadLocal中获取之前存储的 looper对象
mLooper = Looper.myLooper();
if (mLooper == null) {
throw new RuntimeException(
// 必须先调用 Looper.prepare(),然后才可以 在子线程中创建 handler对象,
// 就是最上边的实例代码写法,否则抛出下边异常
"Can't create handler inside thread that has not called Looper.prepare()");
}
// 从 looper中取出 消息队列 MessageQueue
mQueue = mLooper.mQueue;
mCallback = callback;
mAsynchronous = async;
}
然后看发送消息方法 sendMessage():
/**
* 任何的发送消息方法最终都会调用到 下边的方法
*/
public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
// 获取消息队列 MessageQueue
MessageQueue queue = mQueue;
if (queue == null) {
RuntimeException e = new RuntimeException(
this + " sendMessageAtTime() called with no mQueue");
Log.w("Looper", e.getMessage(), e);
return false;
}
return enqueueMessage(queue, msg, uptimeMillis);
}
private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
// msg.target是handler
msg.target = this;
if (mAsynchronous) {
msg.setAsynchronous(true);
}
// 最终会调用 MessageQueue 中的 enqueueMessage()方法,
// 也就是说 handler发出的消息最终会保存到 消息队列中
return queue.enqueueMessage(msg, uptimeMillis);
}
/**
* 在 Handler 的 dispatchMessage中处理 从消息队列MessageQueue中取出的msg
*/
public void dispatchMessage(Message msg) {
if (msg.callback != null) {
handleCallback(msg);
} else {
if (mCallback != null) {
if (mCallback.handleMessage(msg)) {
return;
}
}
// 这个是我们自己实现的 handleMessage()方法,用于更新UI
handleMessage(msg);
}
}
3. 总结
1>:对于Looper.prepare():在ThreadLocal中 保存 一个looper, 在 looper中保存 一个MessageQueue对象,因为 Looper.prepare() 只能调用1次,所以 MessageQueue只有1个;
2>:对于Looper.loop():会让当前线程进入一个死循环(for循环),不断的从MessageQueue中取消息,然后调用 msg.target.dispatchMessage(msg) 把消息给 handler.dispatchMessage(msg);
3>:对于Handler的构造方法Handler(...):首先从 ThreadLocal中获取之前存储的 looper 对象, 然后从 looper中获取 消息队列MessageQueue;
4>:对于 Handler的 sendMessage():把 msg 加入到 消息队列 MessageQueue;
5>:对于 Handler的 handleMessage():更新UI;
网友评论