今天看了一下Android消息机制,查资料加思考,仅作为记录
ThreadLocal
ThreadLocal:为每个线程保存一份变量的副本。
原理:
先看set(),首先获取当前线程t,然后通过getMap(t)获取ThreadLocalMap实例,如果存在,则调用map的set(),否则创建map并传值。
public void set(T value) {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
}
ThreadLocalMap:为ThreadLocal内部类,存有一个Entry[],Entry为键值对,键为ThreadLocal对象,即ThreadLocalMap内部存放着键为ThreadLocal对象的键值对集合。
static class ThreadLocalMap {
...
static class Entry extends WeakReference<ThreadLocal<?>> {
/** The value associated with this ThreadLocal. */
Object value;
Entry(ThreadLocal<?> k, Object v) {
super(k);
value = v;
}
}
private Entry[] table;
....
}
继续看ThreadLocal的getMap(t),可以看出该“map”来自于Thread
ThreadLocalMap getMap(Thread t) {
return t.threadLocals;
}
来到Thread,可以找到如下属性,该值在我们贴的第一段代码的createMap中被初始化,并传入第一次调用set()时的ThreadLocal对象和值。
ThreadLocal.ThreadLocalMap threadLocals = null;
基本可以明白ThreadLocal的原理,每个Thread都持有一个map,该map以ThreadLocal对象为键,我们创建的ThreadLocal在第一次在某个线程中被set()时,该ThreadLocal对象被放入map中,当我们调用get()方法时,获取当前线程的map即可。
MessageQueue
Handler提交的Message最终会放在消息队列MessageQueue中,并由Looper遍历该“队列”获取可以执行的Message并开始执行。
MessageQueue主要有两个方法,enqueueMessage()和next(),顾名思义就是入队和下一个。
enqueueMessage()方法如下,不难看出为一个遍历链表,并插入Message的操作
boolean enqueueMessage(Message msg, long when) {
...
msg.markInUse();
msg.when = when;
Message p = mMe