1、Looper总体流程
1-1、Looper.prepare()
- sThreadLocal是一个ThreadLocal对象,可以用来储存Looper
- 先调用sThreadLocal.get()取出Looper对象,判断是否为null,不为空则抛出异常,说明了Looper.prepare()方法不能被调用两次,同时也保证了一个线程中只有一个Looper实例
如果sThreadLocal.get()为null,则实例化一个Looper的实例放入了ThreadLocal
/**
* 将当前线程初始化成Looper,使用前要调用loop,退出后要调用quit
*/
public static void prepare() {
prepare(true);
}
private static void prepare(boolean quitAllowed) {
// 保证了一个线程中只有一个Looper实例
if (sThreadLocal.get() != null) {
throw new RuntimeException("Only one Looper may be created per thread");
}
sThreadLocal.set(new android.os.Looper(quitAllowed));
}
1-2、Looper构造方法
/**
* Looper构造方法
* @param quitAllowed
*/
private Looper(boolean quitAllowed) {
// 实例化一个消息队列
mQueue = new MessageQueue(quitAllowed);
// 保存当前线程
mThread = Thread.currentThread();
}
1-3、Looper.loop()
调用完Looper.prepare()方法,我们才能调用Looper.loop方法。(loop方法中我们先调用了myLooper()取出当前的Looper对象,如果为null,系统会抛出异常,提示我们没有调用Looper.prepare()方法 )
- myLooper()方法取出之前的Looper对象,再取出里面的MessageQueue,通过一个for死循环轮询里面的消息
MessageQueue.next取出一个消息,如果消息为null,return并阻塞,如果有消息就调用msg.target.dispatchMessage(msg)进行消息分发,这个target就是Handler,最终在Handler的handlerMessage处理消息
/**
* loop循环消息队列
*/
public static void loop() {
// 1 取出当前的Looper,为空则证明没有执行prepare方法,抛出异常
final android.os.Looper me = myLooper();
if (me == null) {
throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
}
// 2 拿到该looper实例中的mQueue(消息队列)
final MessageQueue queue = me.mQueue;
// 3 循环消息队列中消息
for (;;) {
// 4 取出一条消息,如果没有消息则阻塞
Message msg = queue.next(); // might block
if (msg == null) {
// No message indicates that the message queue is quitting.
return;
}
// 5 使用调用 msg.target.dispatchMessage(msg);
// 把消息交给msg的target的dispatchMessage方法去处理(msg.target就是Handler)
try {
msg.target.dispatchMessage(msg);
} finally {
if (traceTag != 0) {
Trace.traceEnd(traceTag);
}
}
}
}
1-4、loop空消息会阻塞
点击loop,日志如下
- D/MainActivity: prepare before
- D/MainActivity: prepare after
点击quit,日志如下
D/MainActivity: loop after
private Looper looper;
public void loop(View view) {
new Thread(new Runnable() {
@Override
public void run() {
Log.d(TAG, "prepare before");
Looper.prepare();
looper = Looper.myLooper();
Log.d(TAG, "prepare after");
// MessageQueen中消息空则会阻塞线程
Looper.loop();
Log.d(TAG, "loop after");
}
}).start();
}
public void quit(View view) {
looper.quit();
}
1-5、Looper常见方法
prepare:初始化当前线程的Looper
- loop:循环消息队列
- quit:退出消息队列
- myLooper:获取当前线程的Looper对象
- getMainLooper:获取主线程的Looper对象
prepareMainLooper:初始化主线程的Looper
2、Looper简化的代码
``` public final class Looper {
/**
ThreadLocal并不是线程,它的作用是存储Looper */ // sThreadLocal.get() will return null unless you’ve called prepare() static final ThreadLocal
sThreadLocal = new ThreadLocal (); /**
主线程的Looper */ private static android.os.Looper sMainLooper;
/**
消息队列 */ final MessageQueue mQueue;
/**
当前线程Thread */ final Thread mThread;
/**
将当前线程初始化成Looper,使用前要调用loop,退出后要调用quit */ public static void prepare() { prepare(true); }
private static void prepare(boolean quitAllowed) { // 保证了一个线程中只有一个Looper实例 if (sThreadLocal.get() != null) {
throw new RuntimeException("Only one Looper may be created per thread");
} sThreadLocal.set(new android.os.Looper(quitAllowed)); }
/**
- Looper构造方法
@param quitAllowed */ private Looper(boolean quitAllowed) { // 实例化一个消息队列 mQueue = new MessageQueue(quitAllowed); // 保存当前线程 mThread = Thread.currentThread(); }
/**
获取与当前线程关联的Looper,如果没有先调用prepare这里会返回空 */ public static @Nullable android.os.Looper myLooper() { return sThreadLocal.get(); }
/**
loop循环消息队列 */ public static void loop() {
// 1 取出当前的Looper,为空则证明没有执行prepare方法,抛出异常 final android.os.Looper me = myLooper(); if (me == null) {
throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
}
// 2 拿到该looper实例中的mQueue(消息队列) final MessageQueue queue = me.mQueue;
// 3 循环消息队列中消息 for (;;) {
// 4 取出一条消息,如果没有消息则阻塞
Message msg = queue.next(); // might block
if (msg == null) {
// No message indicates that the message queue is quitting.
return;
}
// 5 使用调用 msg.target.dispatchMessage(msg);
// 把消息交给msg的target的dispatchMessage方法去处理(msg.target就是Handler)
try {
msg.target.dispatchMessage(msg);
} finally {
if (traceTag != 0) {
Trace.traceEnd(traceTag);
}
}
} }
/**
* 退出Looper
*/
public void quit() {
mQueue.quit(false);
}
/**
* Android 环境会创建主线程 Looper,开发者不应该自己调用这个方法。
* UI线程,它就是 ActivityThread
* ActivityThread 被创建时就会初始化 Looper,这也是在主线程中默认可以使用 Handler 的原因
*/
@Deprecated
public static void prepareMainLooper() {
prepare(false);
synchronized (android.os.Looper.class) {
if (sMainLooper != null) {
throw new IllegalStateException("The main Looper has already been prepared.");
}
sMainLooper = myLooper();
}
}
/**
* 获取主线程的Looper
* @return
*/
public static android.os.Looper getMainLooper() {
synchronized (android.os.Looper.class) {
return sMainLooper;
}
}
} ```