Android Handler之ThreadLocal分析

一、作用

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 sThreadLocal = new ThreadLocal();

那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的一个工具。

你可能感兴趣的:(Android Handler之ThreadLocal分析)