本文共 3866 字,大约阅读时间需要 12 分钟。
Handler 机制是 Android 开发的基础知识,常见于面试中。如今,在面试中很少直接要求详细讲解 Handler 的机制,而是通过具体场景来测试候选人的理解深度。IdleHandler 因为相对少人使用,因此了解它的功能和使用场景尤为重要。
本文将深入探讨 Android Framework 中的 Handler 机制,特别是 IdleHandler 的功能、使用方法以及在开发中的适用场景。
Handler 是 Android 中常用的事件驱动模型,核心由三部分组成:
注意: 早期,Handler 机制允许开发者自定义事件处理逻辑,消息循环由 Looper管理。
IdleHandler 是 Handler 机制提供的一种在队列空闲时执行任务的额外功能。
IdleHandler 接口定义在 MessageQueue 中:
public static interface IdleHandler { boolean queueIdle();}
重要性:
true
表示是长期IdleHandler,会在下次空闲时重复执行;返回 false
表示为一次性IdleHandler,只能运行一次。要使用IdleHandler,需在 MessageQueue 中添加和移除IdleHandler:
// MessageQueue.javapublic void addIdleHandler(@NonNull IdleHandler handler) { synchronized (this) { mIdleHandlers.add(handler); }}public void removeIdleHandler(@NonNull IdleHandler handler) { synchronized (this) { mIdleHandlers.remove(handler); }}
关键点:
-IdleHandler 在哪些场景下执行?队列空闲有两种状态:
IdleHandler 的核心逻辑在 MessageQueue.next()
方法中:
Message next() { // ...其他逻辑... int pendingIdleHandlerCount = -1; int nextPollTimeoutMillis = 0; for (;;) { nativePollOnce(ptr, nextPollTimeoutMillis); synchronized (this) { // ...现有消息处理逻辑... // 如果有消息,处理,否则设置nextPollTimeoutMillis = -1; // 如果pendingIdleHandlerCount < 0,则获取mIdleHandlers.size(); // 如果mMessages为空或mMessages.when < now,则执行IdleHandler; if (pendingIdleHandlerCount < 0 && (mMessages == null || now < mMessages.when)) { pendingIdleHandlerCount = mIdleHandlers.size(); } // 如果pendingIdleHandlerCount <= 0,阻塞当前线程; if (pendingIdleHandlerCount <= 0) { mBlocked = true; continue; } // 将mIdleHandlers转换为数组处理; if (mPendingIdleHandlers == null) { mPendingIdleHandlers = new IdleHandler[Math.max(pendingIdleHandlerCount, 4)]; } mPendingIdleHandlers = mIdleHandlers.toArray(mPendingIdleHandlers); // 遍历并执行IdleHandler; for (int i = 0; i < pendingIdleHandlerCount; i++) { final IdleHandler idler = mPendingIdleHandlers[i]; mPendingIdleHandlers[i] = null; // 执行队列超时逻辑; try { keep = idler.queueIdle(); } catch (Throwable t) { //日志处理... } // 如果keep 为false,移除该IdleHandler; if (!keep) { synchronized (this) { mIdleHandlers.remove(idler); } } } pendingIdleHandlerCount = 0; nextPollTimeoutMillis = 0; // 重置布置属性... } }}
-由当前MessageQueue所属的Looper线程执行,可以在子线程构造Looper后使用。
IdleHandler 是Handler机制中的一个灵活工具,适用于需要在消息队列空闲时执行任务的场景。但其执行时机基于MessageQueue的状态,不可控,应用时需谨慎。
转载地址:http://ppxtz.baihongyu.com/