在看Handler源码的时候看到了 handler 构造函数中
public Handler(Callback callback, boolean async) {
if (FIND_POTENTIAL_LEAKS) {
final Class extends Handler> klass = getClass();
if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&
(klass.getModifiers() & Modifier.STATIC) == 0) {
Log.w(TAG, "The following Handler class should be static or leaks might occur: " +
klass.getCanonicalName());
}
}
mLooper = Looper.myLooper(); //这一句
if (mLooper == null) {
throw new RuntimeException(
"Can't create handler inside thread that has not called Looper.prepare()");
}
mQueue = mLooper.mQueue;
mCallback = callback;
mAsynchronous = async;
}
调用 mLooper = Looper.myLooper();
static final ThreadLocal
看 myLooper()方法
public static Looper myLooper() {
return sThreadLocal.get();
}
发现sThreadLocal是一个Threadlocal类 于是不解是如何通过这个对象获取到looper对象的 查看ThreadLocal的源码
public void set(T value) {
Thread currentThread = Thread.currentThread(); //获取当前线程
Values values = values(currentThread); //获取当前线程中的values
if (values == null) { //如果没有 那么 new一个
values = initializeValues(currentThread);
}
values.put(this, value); //得到values之后 将 当前 ThreadLocal和Thread关联 经过一些映射 找到一个合适的位置存放 ThreadLocal
//下一个位置存放存放的内容
}
@SuppressWarnings("unchecked")
public T get() { //获取的时候 先获取当前线程 得到当前线程的 values 如果得到了 那么得到values中的table 经过映射获取要得到的位置 然后取下一个位置
//就是要得到的值。 如果没找到 那么就创建一个返回。。
// Optimized for the fast path.
Thread currentThread = Thread.currentThread();
Values values = values(currentThread);
if (values != null) {
Object[] table = values.table;
int index = hash & values.mask;
if (this.reference == table[index]) {
return (T) table[index + 1];
}
} else {
values = initializeValues(currentThread);
}
return (T) values.getAfterMiss(this);
}
其中 源码 注解中解释说 这个方法将返回一个和当前线程相关的Entry 如果不存在 将创建一个 也就是说 这个方法可以返回一个 与当前线程相关的Looper 对象
其中在Looper中 存在一个
static final ThreadLocal
这个对象在prepare()的时会根据当前线程放入一个looper对象 所以Looper中的sThreadLocal中 会存放很多looper对象 根据线程对象来获取线程相关的looper即可