Android中View绘制过程(一) decorView绘制

本文深入探讨了Android中Activity从启动到显示的过程,重点关注了decorView的添加方式及performTraversals()方法的首次调用时机。通过ActivityThread.handleResumeActivity()函数分析,揭示了WindowManager如何管理视图布局。

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

第一次

Activity的显示是在onResume()之后这一点大家都知道,代码在ActivityThread中,还是不去管Activity的启动过程,只去看一下在没有setContentView的时候decorView这里是怎么添加的并且第一调用performTraversals()的。

在ActivityThread.java中,代码

handleResumeActivity()函数中调用wm.addView(decor, l);将decorView添加。

在WindowManagerImpl代码如下

@Override
    public void addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {
        applyDefaultToken(params);
        mGlobal.addView(view, params, mContext.getDisplay(), mParentWindow);
    }

在WindowManagerGlobal代码太多不粘贴了有这样的调用

view.setLayoutParams(wparams);

点进入之后

public void setLayoutParams(ViewGroup.LayoutParams params) {
        if (params == null) {
            throw new NullPointerException("Layout parameters cannot be null");
        }
        mLayoutParams = params;
        resolveLayoutParams();
        if (mParent instanceof ViewGroup) {
            ((ViewGroup) mParent).onSetLayoutParams(this, params);
        }
        requestLayout();
    }

最后这句requestLayout(),这应该是第一回的调用吧。点进去

 if (mParent != null && !mParent.isLayoutRequested()) {
            mParent.requestLayout();
        }

这里mParent就是ViewRootImp看一下这个调用

@Override
    public void requestLayout() {
        if (!mHandlingLayoutInLayoutRequest) {
            checkThread();
            mLayoutRequested = true;
            scheduleTraversals();
        }
    }


调用如下代码

void scheduleTraversals() {
        if (!mTraversalScheduled) {
            mTraversalScheduled = true;
            mTraversalBarrier = mHandler.getLooper().getQueue().postSyncBarrier();
            mChoreographer.postCallback(
                    Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);
            if (!mUnbufferedInputDispatch) {
                scheduleConsumeBatchedInput();
            }
            notifyRendererOfFramePending();
            pokeDrawLockIfNeeded();
        }
    }

post这个Runnable

final class TraversalRunnable implements Runnable {
        @Override
        public void run() {
            doTraversal();
        }
    }

继续调用就到了熟悉的代码了,performTraversals()。 

void doTraversal() {
        if (mTraversalScheduled) {
            mTraversalScheduled = false;
            mHandler.getLooper().getQueue().removeSyncBarrier(mTraversalBarrier);

            if (mProfile) {
                Debug.startMethodTracing("ViewAncestor");
            }

            performTraversals();

            if (mProfile) {
                Debug.stopMethodTracing();
                mProfile = false;
            }
        }
    }

第二次 

WindowManagerGlobal中接下来调用ViewRootImpl 的setView

root.setView(view, wparams, panelParentView);


// Schedule the first layout -before- adding to the window
                // manager, to make sure we do the relayout before receiving
                // any other events from the system.
                requestLayout();

这里注释写到,是第一次的layout,在Window还没有添加之前的调用。然后才添加Window到界面上

res = mWindowSession.addToDisplay(mWindow, mSeq, mWindowAttributes,
                            getHostVisibility(), mDisplay.getDisplayId(),
                            mAttachInfo.mContentInsets, mAttachInfo.mStableInsets,
                            mAttachInfo.mOutsets, mInputChannel);




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值