一、作用
1、在本例中的作用是为每个线程存储一个Looper对象。
二、原理
1、先看一段Handler的构造函数的源码
198 mLooper = Looper.myLooper();
199 if (mLooper == null) {
200 throw new RuntimeException(
201 "Can't create handler inside thread that has not called Looper.prepare()");
202 }
203 mQueue = mLooper.mQueue;
204 mCallback = callback;
205 mAsynchronous = async;
也就是Handler一个构造函数在执行时,会检查当前线程是不是Looper线程
mLooper = Looper.myLooper();
我们看下Looper的myLooper方法
184 public static @Nullable Looper myLooper() {
185 return sThreadLocal.get();
186 }
再看下Looper的prepare方法
87 private static void prepare(boolean quitAllowed) {
88 if (sThreadLocal.get() != null) {
89 throw new RuntimeException("Only one Looper may be created per thread");
90 }
91 sThreadLocal.set(new Looper(quitAllowed));
92 }
我们再看下sThreadLocal是什么
static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();
那ThreadLocal是如何知道当前线程的Looper对象是那个呢?我们看下ThreadLocal源码的get方法
142 public T get() {
143 Thread t = Thread.currentThread();
144 ThreadLocalMap map = getMap(t);
145 if (map != null) {
146 ThreadLocalMap.Entry e = map.getEntry(this);
147 if (e != null)
148 return (T)e.value;
149 }
150 return setInitialValue();
151 }
getMap方法实现
212 ThreadLocalMap getMap(Thread t) {
213 return t.threadLocals;
214 }
187
我们再看下set方法
179 public void set(T value) {
180 Thread t = Thread.currentThread();
181 ThreadLocalMap map = getMap(t);
182 if (map != null)
183 map.set(this, value);
184 else
185 createMap(t, value);
186 }
再看下createMap方法()实现
224 void createMap(Thread t, T firstValue) {
225 t.threadLocals = new ThreadLocalMap(this, firstValue);
226 }
综上,我们可以看出,每个Thread都有一个threadlocals成员变量,这个变量的类型是ThreadLocalMap。当我们想要传递对象给线程时,需要通过一个ThreadLocal对象把要传递的对象存到目标Thread对象的threadlocals里。所以,ThreadLocal本质上是操作ThreadLocalMaps的一个工具。