1.IdleHandler是一个interface
public final class MessageQueue {
public static interface IdleHandler {
boolean queueIdle();
}
}
2.当MessageQueue无Message
如果mIdleHandlers有IdleHandler需要执行,则触发IdleHandler
public final class MessageQueue {
private final ArrayList<IdleHandler> mIdleHandlers = new ArrayList<IdleHandler>();
private IdleHandler[] mPendingIdleHandlers;
Message next() {
int pendingIdleHandlerCount = -1; // -1 only during first iteration
for (;;) {
synchronized (this) {
//如果没有Message
第一次是因为 pendingIdleHandlerCount = -1 ,取一次 idleHandler 数量
// If first time idle, then get the number of idlers to run.
// Idle handles only run if the queue is empty or if the first message
// in the queue (possibly a barrier) is due to be handled in the future.
if (pendingIdleHandlerCount < 0
&& (mMessages == null || now < mMessages.when)) {
pendingIdleHandlerCount = mIdleHandlers.size();
}
//这次判断大小是确认是否有需要处理的 idlHandler
//如果没有的话,则将 mBlocked 改为阻塞状态
if (pendingIdleHandlerCount <= 0) {
// No idle handlers to run. Loop and wait some more.
mBlocked = true;
continue;
}
//如果有需要执行的 idleHandler,创建mPendingIdleHandlers数组
if (mPendingIdleHandlers == null) {
mPendingIdleHandlers = new
IdleHandler[Math.max(pendingIdleHandlerCount, 4)];
}
//把数组列表中的 idleHandler 复制一份到数组中
mPendingIdleHandlers = mIdleHandlers.toArray(mPendingIdleHandlers);
//遍历数组mPendingIdleHandlers
// Run the idle handlers.
// We only ever reach this code block during the first iteration.
for (int i = 0; i < pendingIdleHandlerCount; i++) {
final IdleHandler idler = mPendingIdleHandlers[i];
//release the reference to the handler
mPendingIdleHandlers[i] = null;
boolean keep = false;
try {
//执行 idleHandler.queueIdle() 方法。
keep = idler.queueIdle();
} catch (Throwable t) {
Log.wtf(TAG, "IdleHandler threw exception", t);
}
//根据 idler.queueIdle() 返回结果判断该消息是否从数组列表中移除。
if (!keep) {
synchronized (this) {
mIdleHandlers.remove(idler);
}
}
}
//重置数量,保证每次 next() 时,只会执行一次 IdleHandler 方法。
// Reset the idle handler count to 0 so we do not run them again.
pendingIdleHandlerCount = 0;
// While calling an idle handler, a new message could have been delivered
// so go back and look again for a pending message without waiting.
nextPollTimeoutMillis = 0;
}
}
}
}
3.添加IdleHandler
public final class MessageQueue {
public void addIdleHandler(@NonNull IdleHandler handler) {
if (handler == null) {
throw new NullPointerException("Can't add a null IdleHandler");
}
synchronized (this) {
mIdleHandlers.add(handler);
}
}
}
4.移除IdleHandler
public final class MessageQueue {
public void removeIdleHandler(@NonNull IdleHandler handler) {
synchronized (this) {
mIdleHandlers.remove(handler);
}
}
}