MessageQueue
MessageQueue.IdleHandler
IdleHandler是MessageQueue内部的一个接口,他是一个空闲处理程序。
就是一个在MessageQueue获取不到Message消息时执行的接口。
我们看看MessageQueue空闲时执行的代码:
Message next() {
int pendingIdleHandlerCount = -1; // -1 only during first iteration
synchronized (this) {
//...
//没有消息时退出队列
if (mQuitting) {
dispose();
return null;
}
if (pendingIdleHandlerCount < 0 && (mMessages == null || now < mMessages.when)) {
pendingIdleHandlerCount = mIdleHandlers.size();
}
if (pendingIdleHandlerCount <= 0) {
// No idle handlers to run. Loop and wait some more.
mBlocked = true;
continue;
}
if (mPendingIdleHandlers == null) {
mPendingIdleHandlers = new IdleHandler[Math.max(pendingIdleHandlerCount, 4)];
}
mPendingIdleHandlers = mIdleHandlers.toArray(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];
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) {
synchronized (this) {
mIdleHandlers.remove(idler);
}
}
}
// 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;
}
}
我去掉了获取Message相关的代码,保留了和IdleHandler相关的逻辑。
上面这段代码很简单,就是判断mIdleHandlers队列是不是空,如果为空就进入等等状态。不为空表示有地方实现了IdleHandler接口。遍历数组内的所有对象,执行空闲处理代码
执行IdleHandler的几个前置条件是:
- 当链表中没有得到需要执行的Message时(消息队列为空或者队列中的Message没有到执行时间)
- 设置了队列获取消息为空不退出队列
- 实现了IdleHandler接口,并调用
addIdleHandler()
添加
IdleHandler的应用场景
ActivityThread内定义了三个内部类,分别实现是:
- Idler
- GcIdler
- PurgeIdler
他们都实现了IdleHandler接口。