IdleHandler 的定义,这里返回 true,表示下次空闲时还会触发。
public static interface IdleHandler {
boolean queueIdle();
}
它的用法
private MessageQueue.IdleHandler mIdleHandler = new MessageQueue.IdleHandler() {
@Override
public boolean queueIdle() {
//do something
}
};
public void start() {
Looper.myQueue().addIdleHandler(mIdleHandler);
}
首先声明 IdleHandler,它的回调 queueIdle 执行相关任务。其次将 idleHandler 添加到 Looper 的 MessageQueue 中。
public void addIdleHandler(@NonNull IdleHandler handler) {
if (handler == null) {
throw new NullPointerException("Can't add a null IdleHandler");
}
synchronized (this) {
mIdleHandlers.add(handler);
}
}
private final ArrayList<IdleHandler> mIdleHandlers = new ArrayList<IdleHandler>();
自然有 add,也有 remove 了
public void removeIdleHandler(@NonNull IdleHandler handler) {
synchronized (this) {
mIdleHandlers.remove(handler);
}
}
怎么判断线程是否 Idle,队列中没有消息,或者头节点的消息触发时间还未到
public boolean isIdle() {
synchronized (this) {
final long now = SystemClock.uptimeMillis();
return mMessages == null || now < mMessages.when;
}
}
重点了解下它在什么情况下触发,继续关注 MessageQueue 的 next 方法。
Message next() {
int pendingIdleHandlerCount = -1; // -1 only during first iteration
int nextPollTimeoutMillis = 0;
for (;;) {
nativePollOnce(ptr, nextPollTimeoutMillis);
synchronized (this) {
//...
//当线程是空闲状态时,取出mIdleHandlers的个数
if (pendingIdleHandlerCount < 0
&& (mMessages == null || now < mMessages.when)) {
pendingIdleHandlerCount = mIdleHandlers.size();
}
//没有的情况
if (pendingIdleHandlerCount <= 0) {
mBlocked = true;
continue;
}
//初始化mPendingIdleHandlers 它时IdleHandler[]数组,最小为4
//将mIdleHandlers转为mPendingIdleHandlers
if (mPendingIdleHandlers == null) {
mPendingIdleHandlers = new IdleHandler[Math.max(pendingIdleHandlerCount, 4)];
}
mPendingIdleHandlers = mIdleHandlers.toArray(mPendingIdleHandlers);
}
//对mPendingIdleHandlers 遍历
for (int i = 0; i < pendingIdleHandlerCount; i++) {
final IdleHandler idler = mPendingIdleHandlers[i];
//置空
mPendingIdleHandlers[i] = null;
boolean keep = false;
try {
//queueIdle函数的返回值
keep = idler.queueIdle();
} catch (Throwable t) {
Log.wtf(TAG, "IdleHandler threw exception", t);
}
//false的话就取移除,和上文所说一直
if (!keep) {
synchronized (this) {
mIdleHandlers.remove(idler);
}
}
}
pendingIdleHandlerCount = 0;
nextPollTimeoutMillis = 0;
}
}
IdleHandler 原理比较简单。它的源码中有很多地方用到。
private static final class EmptyRunnable implements Runnable {
public void run() {
}
}
private static final class Idler implements MessageQueue.IdleHandler {
private final Runnable mCallback;
private boolean mIdle;
public Idler(Runnable callback) {
mCallback = callback;
mIdle = false;
}
public final boolean queueIdle() {
if (mCallback != null) {
mCallback.run();
}
synchronized (this) {
mIdle = true;
notifyAll();
}
return false;
}
public void waitForIdle() {
synchronized (this) {
while (!mIdle) {
try {
wait();
} catch (InterruptedException e) {
}
}
}
}
}
Idler idler = new Idler(null);
mMessageQueue.addIdleHandler(idler);
mThread.getHandler().post(new EmptyRunnable());
idler.waitForIdle();
Android中 Handler 是 Fragmeword 中最基础的,我们必须完全深刻的认识它、理解它。