View的post()源码分析

本文深入解析了View中的post()和postDelayed()方法的工作原理。通过分析源码,揭示了这些方法如何利用Handler机制实现跨线程更新UI,尤其是在onCreate()期间解决View尺寸为0的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

##View的post()和postDelayed()方法详解

###子线程中不能对UI进行操作,这我们都知道,但是可以通过view.post(Runnable)的方式进行UI操作,这是为什么呢?我们通过分析源码的方式来了解一下


    public boolean post(Runnable action) {
        final AttachInfo attachInfo = mAttachInfo;
        if (attachInfo != null) {
            return attachInfo.mHandler.post(action);
        }

        // Postpone the runnable until we know on which thread it needs to run.
        // Assume that the runnable will be successfully placed after attach.
        getRunQueue().post(action);
        return true;
    }


view的post()将Runnable action传递给attachInfo.Handler,所以其本质都是Handler、Looper、MessageQueue、Message的异步消息处理机制,接着再查看mAttachInfo的来源,源码定位到

     void dispatchAttachedToWindow(AttachInfo info, int visibility) {
        mAttachInfo = info;
        ...
    }

####在view的绘制过程中,第一次会调用DecorView的dispatchAttachedToWindow,所以这也就解释了view.post()可以解决在oncreate()中获取view的宽高为0的问题

` getRunQueue().post(action); `当attachInfo为空时会走此方法,getRunQueue()的源码:


    private HandlerActionQueue getRunQueue() {
        if (mRunQueue == null) {
            mRunQueue = new HandlerActionQueue();
        }
        return mRunQueue;
    }

再看HandlerActionQueue的源码:

    public void post(Runnable action) {
        postDelayed(action, 0);
    }

    public void postDelayed(Runnable action, long delayMillis) {
        final HandlerAction handlerAction = new HandlerAction(action, delayMillis);

        synchronized (this) {
            if (mActions == null) {
                mActions = new HandlerAction[4];
            }
            mActions = GrowingArrayUtils.append(mActions, mCount, handlerAction);
            mCount++;
        }
    }

HandlerActionQueue会将runnable缓存起来,最大缓存数为4,缓存起来的Runnable返回到上面的dispatchAttachedToWindow中会被调用
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值