首先看看Looper源码
怎么获取当前线程Looper
/**
* Return the Looper object associated with the current thread. Returns
* null if the calling thread is not associated with a Looper.
*/
public static @Nullable Looper myLooper() {
return sThreadLocal.get();
}
/**
* Return the {@link MessageQueue} object associated with the current
* thread. This must be called from a thread running a Looper, or a
* NullPointerException will be thrown.
*/
public static @NonNull MessageQueue myQueue() {
return myLooper().mQueue;
}
private Looper(boolean quitAllowed) {
mQueue = new MessageQueue(quitAllowed);
mThread = Thread.currentThread();
}
一个线程中只能有一个Looper
在prepare的时候会获取ThreadLocal,如果已经存在Looper则抛出异常,否则创建Looper对象
/** Initialize the current thread as a looper.
* This gives you a chance to create handlers that then reference
* this looper, before actually starting the loop. Be sure to call
* {@link #loop()} after calling this method, and end it by calling
* {@link #quit()}.
*/
private static void prepare(boolean quitAllowed) {
if (sThreadLocal.get() != null) {
throw new RuntimeException("Only one Looper may be created per thread");
}
sThreadLocal.set(new Looper(quitAllowed));
}
怎么保证?
通过ThreadLocal来保证
static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();
其实ThreadLocal只是个傀儡,真正发挥作用的,是线程内的ThreadLocalMap。
ThreadLocal只是作为一个key,并且提供方法,将线程的Looper保存进(取出)ThreadLocalMap,而已,以此来实现每个线程中只需创建一个Looper。
这就是为什么使用ThreadLocal的原因。
网友评论