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

来源:互联网 发布:六轴机械手臂编程 编辑:程序博客网 时间:2024/06/05 10:42

第一次

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);




原创粉丝点击