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的几个前置条件是:

  1. 当链表中没有得到需要执行的Message时(消息队列为空或者队列中的Message没有到执行时间)
  2. 设置了队列获取消息为空不退出队列
  3. 实现了IdleHandler接口,并调用addIdleHandler()添加

IdleHandler的应用场景

ActivityThread内定义了三个内部类,分别实现是:

  1. Idler
  2. GcIdler
  3. PurgeIdler

他们都实现了IdleHandler接口。

posted @ 2023-06-14 13:25  Ysun_top  阅读(42)  评论(0编辑  收藏  举报