第九周总结

时间:2019 年 02 月 25 日 ~ 2019 年 03 月 01 日

一、Handler

Handler 消息机制

Handler 消息机制除了 Handler 本身外,还包含:Looper、MessageQueue、Message,消息机制需要有消息队列、消息循环、消息处理

如下:
Handler:发送消息(Message)到消息队列(MessageQueue)
Looper:遍历消息队列(MessageQueue)中的消息(Message),然后分发给对应的 Handler(谁发送的消息谁处理)
MessageQueue:消息队列,存储消息
Message:消息本身

Handler 消息机制工作流程简图:
第九周总结

在子线程中使用 Handler 的栗子

class MyThread extends Thread {
	public Handler handler;
	
	@Override
	public void run () {
		Looper.prepare();
		Handler = new Handler() {
			@Override
            public void handleMessage(Message msg) {
                // 处理消息
            }
		};
		Looper.loop();
	}
}

使用 Handler 之前,需要调用 Looper#prepare()?

public static void loop() {
	// 获取 Loop 对象
	final Looper me = myLooper();
	// Looper 对象为空
	if (me == null) {
		// 抛异常
		throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
	}
	...
}

消息要经过 Looper#loop() 方法的遍历,然后才能分发给对应的 Handler 去处理,在 loop() 方法的最开始对 Loop 对象是否为空进行了判断

Loop#myLooper():

// sThreadLocal.get() will return null unless you've called prepare().
// 根据泛型可知,sThreadLocal 中存储的是 Looper
// 根据源码注释可知,直到调用了 prepare() 方法,sThreadLocal.get() 返回值才不为空
static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();

public static @Nullable Looper myLooper() {
	// 由上面的 sThreadLocal 可知,需要调用 prepare() 方法,sThreadLocal.get() 返回值才不为空
    return sThreadLocal.get();
}

Loop#prepare():

public static void prepare() {
    prepare(true);
}

private static void prepare(boolean quitAllowed) {
	// 一个线程只能创建一个 Loop
    if (sThreadLocal.get() != null) {
        throw new RuntimeException("Only one Looper may be created per thread");
    }
    // 创建 Looper 对象实例,保存到 sThreadLocal 变量中
    sThreadLocal.set(new Looper(quitAllowed));
}

二、从 ActivityThread#main() 到 Activity#onCreate()

第九周总结