Handler源码解读(四)

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 中最基础的,我们必须完全深刻的认识它、理解它。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值