Handler源码分析
1.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());
}
}
//初始化Looper
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;
}
在调用
public Handler() {
this(null, false);
}
首先final Looper mLooper;初始化
public static @Nullable Looper myLooper() {
return sThreadLocal.get();
}
` 官方解释是这个方法返回一个与当前线程关联起来的Looper,如果没有关联起来,就返回为null . 其中 sThreadLocal是在Looper类中的成员变量 static final ThreadLocal sThreadLocal = new ThreadLocal();
源码中有一个这样的解释 // sThreadLocal.get() will return null unless you've called prepare(). static final ThreadLocal sThreadLocal = new ThreadLocal();
就是说,如果你没有调用prepare(),方法,就会返回null,那么prepare()什么时候执行呢?
为什么在主线程中不需要调用Looper.prepare()方法?
因为在ActivityThread类的main方法中有 `
public static void main(String[] args) {
SamplingProfilerIntegration.start();
CloseGuard.setEnabled(false);
Environment.initForCurrentUser();
// Set the reporter for event logging in libcore
EventLogger.setReporter(new EventLoggingReporter());
Process.setArgV0("<pre-initialized>");
Looper.prepareMainLooper();//这实际就是一个实例化一个looper对象,大家也可以看看prepareMainlooper方法(下方)。
ActivityThread thread = new ActivityThread();
thread.attach(false);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
Looper.loop();//启动循环器
} ` 也就是说,Activity在启动的时候,已经调用了Looper.prepareMainLooper();
此方法的执行如下 `
public static void prepareMainLooper() {
prepare(false);
synchronized (Looper.class) {
if (sMainLooper != null) {
throw new IllegalStateException("The main Looper has already been prepared.");
}
sMainLooper = myLooper();
}
}
在
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));
}
再来看看 sThreadLocal.set(new Looper(quitAllowed));的执行
public void set(T value) {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
}
` 把Looper设置到map中,这里createMap(t,value);
`
void createMap(Thread t, T firstValue) {
t.threadLocals = new ThreadLocalMap(this, firstValue);
}
` 这个firstValue就是new Looper(false);
`
private Looper(boolean quitAllowed) {
mQueue = new MessageQueue(quitAllowed);
mThread = Thread.currentThread();
}
new Looper(false);的时候,就初始化了 消息队列和当前Thread ,然后回过头来看 sThreadLocal.get();
public T get() {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null) {
ThreadLocalMap.Entry e = map.getEntry(this);
if (e != null)
return (T)e.value;
}
return setInitialValue();
}
这里的getMap(t);就不在是null了
ThreadLocalMap getMap(Thread t) {
return t.threadLocals;
}
` 他的返回值是之前就已经new的ThreadLocalMap
然后从Map中取出Entry, `
ThreadLocalMap(ThreadLocal firstKey, Object firstValue) {
table = new Entry[INITIAL_CAPACITY];
int i = firstKey.threadLocalHashCode & (INITIAL_CAPACITY - 1);
table[i] = new Entry(firstKey, firstValue);
size = 1;
setThreshold(INITIAL_CAPACITY);
}
`
ThreadLocalMap的分析
1.初始化一个Entry[16]数组 2.生成一个hashCode的值 3.给生成的这个hashcode的Entry[]赋值,键是firstKey,也就是ThreadLocal,value值,对应的就是 new Looper(false);
然后来看看下面的代码 `
if (map != null) {
ThreadLocalMap.Entry e = map.getEntry(this);
if (e != null)
return (T)e.value;
}
其中getEntry(this),实现如下
private Entry getEntry(ThreadLocal key) {
int i = key.threadLocalHashCode & (table.length - 1);
Entry e = table[i];
if (e != null && e.get() == key)
return e;
else
return getEntryAfterMiss(key, i, e);
}
这里的table.length就是16,也就是这里i值,就是初始化对应的值,而 Entry e = table[i];就是在ThreadLocalMap中构造中的 table[i] = new Entry(firstKey, firstValue); 这里key是this,也就是ThreadLocal,而e.get(),是firstKey,也就是存储时的ThreadLocal 这两个值时同一个值. Entry的构造如下
Entry(ThreadLocal k, Object v) {
super(k);
value = v;
}
`
然后e.value;这个值就是Looper,也就是前面的new Looper(false); 到这里Looper就完成了初始化.
消息队列MessageQueue的初始化
前面在初始化Looper的时候,就初始化了MessageQueue `
private Looper(boolean quitAllowed) {
mQueue = new MessageQueue(quitAllowed);
mThread = Thread.currentThread();
}
而MessageQueue它的构造函数如下:
MessageQueue(boolean quitAllowed) {
mQuitAllowed = quitAllowed;
mPtr = nativeInit();
}
那么到这里,Handler中的成员变量都初始化了
final Looper mLooper;
final MessageQueue mQueue;
final Callback mCallback;
final boolean mAsynchronous;
`
Handler中的消息发送
主要有如下几个方法 1. `
public final boolean sendMessage(Message msg)
{
return sendMessageDelayed(msg, 0);
}
2.
public final boolean sendEmptyMessage(int what)
{
return sendEmptyMessageDelayed(what, 0);
}
3.
public final boolean sendEmptyMessageDelayed(int what, long delayMillis) {
Message msg = Message.obtain();
msg.what = what;
return sendMessageDelayed(msg, delayMillis);
}
4.
public final boolean sendEmptyMessageAtTime(int what, long uptimeMillis) {
Message msg = Message.obtain();
msg.what = what;
return sendMessageAtTime(msg, uptimeMillis);
}
5.
public final boolean sendMessageDelayed(Message msg, long delayMillis)
{
if (delayMillis < 0) {
delayMillis = 0;
}
return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
}
6.
public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
MessageQueue queue = mQueue;
if (queue == null) {
RuntimeException e = new RuntimeException(
this + " sendMessageAtTime() called with no mQueue");
Log.w("Looper", e.getMessage(), e);
return false;
}
return enqueueMessage(queue, msg, uptimeMillis);
}
7.
public final boolean sendMessageAtFrontOfQueue(Message msg) {
MessageQueue queue = mQueue;
if (queue == null) {
RuntimeException e = new RuntimeException(
this + " sendMessageAtTime() called with no mQueue");
Log.w("Looper", e.getMessage(), e);
return false;
}
return enqueueMessage(queue, msg, 0);
}
`
以上的方法,最终都会调用 `
public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
MessageQueue queue = mQueue;
if (queue == null) {
RuntimeException e = new RuntimeException(
this + " sendMessageAtTime() called with no mQueue");
Log.w("Looper", e.getMessage(), e);
return false;
}
return enqueueMessage(queue, msg, uptimeMillis);
}
创建一个Message,当做参数传进来,时间间隔 然后调用enqueueMessage(queue, msg, uptimeMillis); 这个方法的实现如下:
private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
msg.target = this;
if (mAsynchronous) {
msg.setAsynchronous(true);
}
return queue.enqueueMessage(msg, uptimeMillis);
}
this指的是Handler,而mAsynchronous这个值默认是false 所以主要方法流程执行到queue.enqueueMessage(msg, uptimeMillis); 看看他的实现
boolean enqueueMessage(Message msg, long when) {
if (msg.target == null) {
throw new IllegalArgumentException("Message must have a target.");
}
if (msg.isInUse()) {
throw new IllegalStateException(msg + " This message is already in use.");
}
synchronized (this) {
if (mQuitting) {
IllegalStateException e = new IllegalStateException(
msg.target + " sending message to a Handler on a dead thread");
Log.w(TAG, e.getMessage(), e);
msg.recycle();
return false;
}
msg.markInUse();
msg.when = when;
Message p = mMessages;
boolean needWake;
if (p == null || when == 0 || when < p.when) {
// New head, wake up the event queue if blocked.
msg.next = p;
mMessages = msg;
needWake = mBlocked;
} else {
// Inserted within the middle of the queue. Usually we don't have to wake
// up the event queue unless there is a barrier at the head of the queue
// and the message is the earliest asynchronous message in the queue.
needWake = mBlocked && p.target == null && msg.isAsynchronous();
Message prev;
for (;;) {
prev = p;
p = p.next;
if (p == null || when < p.when) {
break;
}
if (needWake && p.isAsynchronous()) {
needWake = false;
}
}
msg.next = p; // invariant: p == prev.next
prev.next = msg;
}
// We can assume mPtr != 0 because mQuitting is false.
if (needWake) {
nativeWake(mPtr);
}
}
return true;
}
` 先看下面这段逻辑
`
synchronized (this) {
...省略
msg.markInUse();
msg.when = when;
Message p = mMessages;
boolean needWake;
if (p == null || when == 0 || when < p.when) {
// New head, wake up the event queue if blocked.
msg.next = p;
mMessages = msg;
needWake = mBlocked;
}
...省略
// We can assume mPtr != 0 because mQuitting is false.
if (needWake) {
nativeWake(mPtr);
}
return true;
` 首先 给消息标记为正在使用, 然后赋值一些基本信息 把下一个节点 赋值为p,默认为null ,然后给当前的消息,赋值给mMessages 设置阻塞标志
然后返回 true
回到前面ActivityThread中的Looper.loop方法 看看他的实现 `
public static void loop() {
//取出当前的Looper
final Looper me = myLooper();
if (me == null) {
throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
}
//给消息队列赋值
final MessageQueue queue = me.mQueue;
// Make sure the identity of this thread is that of the local process,
// and keep track of what that identity token actually is.
Binder.clearCallingIdentity();
final long ident = Binder.clearCallingIdentity();
for (;;) {
//从消息队列中取出Message
Message msg = queue.next(); // might block
if (msg == null) {
// No message indicates that the message queue is quitting.
return;
}
// This must be in a local variable, in case a UI event sets the logger
final Printer logging = me.mLogging;
if (logging != null) {
logging.println(">>>>> Dispatching to " + msg.target + " " +
msg.callback + ": " + msg.what);
}
//做出一些跟踪标志
final long traceTag = me.mTraceTag;
if (traceTag != 0 && Trace.isTagEnabled(traceTag)) {
Trace.traceBegin(traceTag, msg.target.getTraceName(msg));
}
try {
//然后调用mHandler的dispatchMessage(msg);这里的target就是发送消息时绑定的Handler
msg.target.dispatchMessage(msg);
} finally {
//结束消息的跟踪
if (traceTag != 0) {
Trace.traceEnd(traceTag);
}
}
if (logging != null) {
logging.println("<<<<< Finished to " + msg.target + " " + msg.callback);
}
// Make sure that during the course of dispatching the
// identity of the thread wasn't corrupted.
final long newIdent = Binder.clearCallingIdentity();
if (ident != newIdent) {
Log.wtf(TAG, "Thread identity changed from 0x"
+ Long.toHexString(ident) + " to 0x"
+ Long.toHexString(newIdent) + " while dispatching to "
+ msg.target.getClass().getName() + " "
+ msg.callback + " what=" + msg.what);
}
msg.recycleUnchecked();
}
}
` 注意到,调用looper.loop()方法,会执行 msg.target.dispatchMessage(msg); 所以要处理发送的消息时,就必须重写这个方法
上面的 msg.recycleUnchecked();对消息进行回收处理. `
void recycleUnchecked() {
// Mark the message as in use while it remains in the recycled object pool.
// Clear out all other details.
flags = FLAG_IN_USE;
what = 0;
arg1 = 0;
arg2 = 0;
obj = null;
replyTo = null;
sendingUid = -1;
when = 0;
target = null;
callback = null;
data = null;
synchronized (sPoolSync) {
if (sPoolSize < MAX_POOL_SIZE) {
next = sPool;
sPool = this;
sPoolSize++;
}
}
}
`
回过头来看一下流程,首先我们在Activity启动的时候,就会执行一个 Looper.prepareMainLooper(); 和 Looper.loop(); 如果我们在主线程中new Handler(); 那么就会执行this.Handler(null,false); 这个构造方法里会初始化 Looper.myLooper(); 和mLooper.mQueue,消息队列
Looper.myLooper 会执行ThreadLocal中的get方法 static final ThreadLocal sThreadLocal = new ThreadLocal();