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;
}
构造函数二
public Handler(Looper looper, Callback callback, boolean async) {
mLooper = looper;
mQueue = looper.mQueue;
mCallback = callback;
mAsynchronous = async;
}
其他构造函数,最终会调用上面两个构造函数中的一个。
四个重要的成员变量
mLooper
当构造函数没有传入 Looper 对象,会通过 Looper.myLooper() 获取 Looper。
如果 Looper.myLooper 为空,抛出异常。
mQueue
mLooper.mQueue 对象
mCallback
自定义 callback
mAsynchronous
Android 在 View 绘制过程中会添加一个 Barrier 。
添加 Barrier 以后,消息队列就会暂停执行。
如果设置了 mAsynchronous =true ,则会继续执行。
核心函数
handler sendMessageXXX()、postXXX() 最后会调用到 enqueueMessage 、sendMessageAtTime
private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
msg.target = this;
if (mAsynchronous) {
msg.setAsynchronous(true);
}
return queue.enqueueMessage(msg, uptimeMillis);
}
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);
}
Runnable 转换为 Message
private static Message getPostMessage(Runnable r) {
Message m = Message.obtain();
m.callback = r;
return m;
}
分析一下上面的函数
1、postXXX() 传入的 Runnable 会被封装为一个 Message
2、msg.target = this ,讲当前 handler 对象引用赋值给 Message
3、Message 会被添加到 MessageQueue 之中。
3、如果设置了 mAsynchronous 会 true,Message会执行 msg.setAsynchronous(true)
handler 回调
Looper 对象会遍历 MessageQueue 中的 Message,然后执行 msg.target.dispatchMessage(msg)
public void dispatchMessage(Message msg) {
if (msg.callback != null) {
handleCallback(msg);
} else {
if (mCallback != null) {
if (mCallback.handleMessage(msg)) {
return;
}
}
handleMessage(msg);
}
}
分析以上代码
1、如果 msg.callback !=null ,即 msg 为一个 Runnable 。
调用 handleCallback(msg) 执行 msg.callback.run()
2、如果 mCallback != null ,即自定义了 Callback 。
调用 mCallback.handleMessage(msg),如果返回 true ,方法结束。
否则再次调用 handleMessage(msg)
3、如果 mCallback == null ,handleMessage(msg) 。
Looper
创建 Looper
构造函数
private Looper(boolean quitAllowed) {
mQueue = new MessageQueue(quitAllowed);
mThread = Thread.currentThread();
}
prepare
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));
}
myLooper
public static @Nullable Looper myLooper() {
return sThreadLocal.get();
}
sMainLooper 相关方法
public static void prepareMainLooper() {
prepare(false);
synchronized (Looper.class) {
if (sMainLooper != null) {
throw new IllegalStateException("The main Looper has already been prepared.");
}
sMainLooper = myLooper();
}
}
public static Looper getMainLooper() {
synchronized (Looper.class) {
return sMainLooper;
}
}
总结以上方法
1、私有构造函数,外部无法创建 Looper 对象。
2、只有 Looper.prepare() 可以创建 Looper 对象
3、一个线程只能创建一个 Looper 对象。
4、Looper 创建时会创建一个 MessageQueue
5、只能通过 myLooper 获得当前线程的 Looper 对象。
7、Android 程序创建的时候会初始化 Looper 的 sMainLooper。
8、非 UI 线程可以通过 getMainLooper 获得主线程的 Looper
Looper.loop()
Looper 最主要的功能就是一直遍历 MessageQueue 中的 Message 队列,直到队列中 Message 为空,就结束改方法。
该方法会一直阻塞线程,所以 Looper.loop() 以后的代码不会被执行。
public static void loop() {
……
for (;;) {
Message msg = queue.next(); // might block
if (msg == null) {
// No message indicates that the message queue is quitting.
return;
}
……
try {
msg.target.dispatchMessage(msg);
} finally {
if (traceTag != 0) {
Trace.traceEnd(traceTag);
}
}
……
}
}
停止 Looper
public void quit() {
mQueue.quit(false);
}
MessageQueue
构造函数
MessageQueue(boolean quitAllowed) {
mQuitAllowed = quitAllowed;
mPtr = nativeInit();
}
nativeInit 会创建一个 native 层的 NativeMessageQueue
入队
boolean enqueueMessage(Message msg, long when) {
……
synchronized (this) {
if (mQuitting) {
……
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 {
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;
}
if (needWake) {
nativeWake(mPtr);
}
}
return true;
}
Message 是一个链表结构,enqueueMessage() 函数的作用就是添加一个 Message 到 mMessages 链表之中。
出队
Message next() {
……
for (;;) {
if (nextPollTimeoutMillis != 0) {
Binder.flushPendingCommands();
}
nativePollOnce(ptr, nextPollTimeoutMillis);
synchronized (this) {
……
Message msg = mMessages;
if (msg != null && msg.target == null) {
do {
prevMsg = msg;
msg = msg.next;
} while (msg != null && !msg.isAsynchronous());
}
if (msg != null) {
if (now < msg.when) {
……
} else {
mBlocked = false;
if (prevMsg != null) {
prevMsg.next = msg.next;
} else {
mMessages = msg.next;
}
msg.next = null;
msg.markInUse();
return msg;
}
} else {
nextPollTimeoutMillis = -1;
}
……
}
}
分析一下 MessageQueue 的上述方法
1、next() 函数会遍历 mMessages 链表,取出一个 Message 对象返回给 Looper.loop() 方法。
2、如果当期链表为空,则调用 nativePollOnce(ptr, nextPollTimeoutMillis) 阻塞方法。
3、enqueueMessage() 方法中的 nativeWake(mPtr) 可以唤醒阻塞。
4、next() 方法中,如果 mMessages 队头是一个 Barrier,则 msg.isAsynchronous() = true 的消息出队。
nativePollOnce(long ptr, int timeoutMillis) 和 nativeWake(long ptr)
这一组方法通过调用 Linux epoll 系列函数实现阻塞机制。