MessageQueue.next()
Message next() {
final long ptr = mPtr; //mPtr是通过native方法生成的code,作用是将其与Native层的消息队列绑定
if (ptr == 0) {
//如果没有与Native层的队列绑定则直接返回
return null;
}
int pendingIdleHandlerCount = -1; //保存IdleHandler的个数
int nextPollTimeoutMillis = 0; //下一次消息到来需要等待的时间
for (;;) {
if (nextPollTimeoutMillis != 0) {
//没有需要等待的消息,释放资源。
Binder.flushPendingCommands();
}
//1)nextPollTimeoutMillis > 0 进入阻塞,nextPollTimeoutMillis时间后再次获取消息 //2) nextPollTimeoutMillis < 0 进入阻塞等待唤醒
nativePollOnce(ptr, nextPollTimeoutMillis);
synchronized (this) {
final long now = SystemClock.uptimeMillis(); //记录当前的时间
Message prevMsg = null;
Message msg = mMessages; //队列中的第一个消息
if (msg != null && msg.target == null) {
//发现有消息屏障(msg.target == null表示此消息为消息屏障)
do {
prevMsg = msg;
msg = msg.next;
} while (msg != null && !msg.isAsynchronous());//找到第一个异步消息
}
if (msg != null) {
//找到了可执行消息
if (now < msg.when) {
// 消息的执行时间还没有到,更新nextPollTimeoutMillis等待时间
nextPollTimeoutMillis = (int) Math.min(msg.when - now, Integer.MAX_VALUE);
} else {
//到了执行的时间,控制队列不再阻塞,并操作当前队列移除这个消息。
mBlocked = false;
if (prevMsg != null) {
prevMsg.next = msg.next;
} else {
mMessages = msg.next;
}
msg.next = null;
if (DEBUG) Log.v(TAG, "Returning message: " + msg);
// 设置msg正在使用
msg.markInUse();
return msg; //返回这个消息
}
} else {
//没有获取到可执行的消息 nextPollTimeoutMillis设置为-1,下一次循环会进入休眠状态
nextPollTimeoutMillis = -1;
}
// Process the quit message now that all pending messages have been handled.
if (mQuitting) {
//如果队列需要退出,则退出循环返回null,同时销毁队列
dispose();
return null;
}
//接下来进行IdleHandler的处理
if (pendingIdleHandlerCount < 0
&& (mMessages == null || now < mMessages.when)) {
// 初始化IdleHandler的个数
pendingIdleHandlerCount = mIdleHandlers.size();
}
if (pendingIdleHandlerCount <= 0) {
//没有需要执行的IdelHandler则继续下一次循环
mBlocked = true;
continue;
}
//存储IdleHandler的数组最小长度是4
if (mPendingIdleHandlers == null) {
mPendingIdleHandlers = new IdleHandler[Math.max(pendingIdleHandlerCount, 4)];
}
mPendingIdleHandlers = mIdleHandlers.toArray(mPendingIdleHandlers);//从mIdleHandlers里面进行拷贝
}
//依次执行IdleHandler
for (int i = 0; i < pendingIdleHandlerCount; i++) {
final IdleHandler idler = mPendingIdleHandlers[i];
mPendingIdleHandlers[i] = null; // release the reference to the handler
boolean keep = false;
try {
keep = idler.queueIdle();
} catch (Throwable t) {
Log.wtf(TAG, "IdleHandler threw exception", t);
}
if (!keep) {
//keep为true则执行完毕不移除,下次可继续执行,否则移除。
synchronized (this) {
mIdleHandlers.remove(idler);
}
}
}
//重置等待时间和idleHandler个数
pendingIdleHandlerCount = 0;
nextPollTimeoutMillis = 0;
}
}
执行步骤
1)通过native方法生成的code,将其与Native层的消息队列绑定。
2)判断是否需要阻塞等待(等待多长时间)。
3)判断是否有消息屏障,有屏障则取出第一个异步消息。
4)消息到达了执行时间就立即执行,否则在下一次循环阻塞等待。
5)当前没有可执行的消息则进行处理IdleHandler
总结
1)通过与Native队列建立关联实现阻塞和唤醒。
2)优先处理异步消息,如果消息没有到达执行时间则阻塞等待。
3)没有可执行消息则执行IdleHandler。