在ActivityThread#main()方法中,有调用Looper.prepareMainLooper()
、Looper.loop()
,平时也经常使用Looper.prepare()
、Looper.myLooper()
这些方法。我们仔细看看这些方法里面到底做了什么。
prepareMainLooper()
private static Looper sMainLooper;
public static void prepareMainLooper() {
//因为是主线程,所以不允许退出
//生成不允许退出的Looper对象
prepare(false);
synchronized (Looper.class) {
if (sMainLooper != null) {
//线程只能执行一次,第二次执行就会抛出异常。
throw new IllegalStateException("The main Looper has already been prepared.");
}
//取出刚才生成的Looper对象,赋值给sMainLooper
//getMainLooper()可以获取这个成员变量
sMainLooper = myLooper();
}
}
getMainLooper()
public static Looper getMainLooper() {
synchronized (Looper.class) {
return sMainLooper;
}
}
prepare()
new一个Looper对象,保存在ThreadLocal中。这个方法只能执行一次。
public static void prepare() {
//true表示允许退出,一般子线程的looper都是允许退出的。
prepare(true);
}
private static void prepare(boolean quitAllowed) {
//每个线程只允许执行一次该方法,第二次执行,线程的ThreadLocal已有数据,则会抛出异常。
if (sThreadLocal.get() != null) {
throw new RuntimeException("Only one Looper may be created per thread");
}
//创建Looper对象,并且保存到当前线程的ThreadLocal中
sThreadLocal.set(new Looper(quitAllowed));
}
private Looper(boolean quitAllowed) {
mQueue = new MessageQueue(quitAllowed);
mThread = Thread.currentThread();
}
Looper对象不能直接创建,必须通过Looper来的两个public static方法prepare()或者prepareMainLooper()来间接创建。因为:Looper的构造方法是私有的。
myLooper()
从ThreadLocal里面取出Looper对象。
// sThreadLocal.get() will return null unless you've called prepare().
static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();
public static @Nullable Looper myLooper() {
return sThreadLocal.get();
}