ViewRoot对应ViewRootImpl,是链接WindowManager 和DecorView的纽带。View的三大流程都是经过ViewRoot完成的,如图所示, ![ViewRootImpl 的代码结构图] java
ViewRootImpl.addConfigurationChange(Configuration newConfig),经过mH 发送消息 what = 118 的值到H 中处理 调用了 ActivityThread 的 handleConfigurationChanged
复制代码
能够说ViewRootImpl控制这整个View的绘制流程,是很是重要的,当Activity被建立时,会将DecorView添加到Window中,同时会建立ViewRootImpl对象.api
ActivityThread#handleResumeActivity wm.addView(decor,l),经过WindowManager 将decor添加到window中,l是LayoutParams,核心代码以下:api25的源码ide
WindowManager wm;
if (r.window == null && !a.mFinished && willBeVisible) {
r.window = r.activity.getWindow();
View decor = r.window.getDecorView();
decor.setVisibility(4);
wm = a.getWindowManager();
LayoutParams l = r.window.getAttributes();
a.mDecor = decor;
l.type = 1;
l.softInputMode |= forwardBit;
if (r.mPreserveWindow) {
a.mWindowAdded = true;
r.mPreserveWindow = false;
ViewRootImpl impl = decor.getViewRootImpl();
if (impl != null) {
impl.notifyChildRebuilt();
}
}
if (a.mVisibleFromClient && !a.mWindowAdded) {
a.mWindowAdded = true;
wm.addView(decor, l);
}
} else if (!willBeVisible) {
r.hideForNow = true;
}
复制代码
wm.addView(decor, l)通过 WindowManagerImpl再到WindowManagerGlobal 中的 addView方法,在此方法里面对ViewRootImpl 进行了初始化。post
ViewRootImpl root = new ViewRootImpl(view.getContext(), display);
root.setView(view, wparams, panelParentView);
复制代码
View的绘制流程是从performTraversals执行遍历开始的,通过measure,layout,draw,三个过程才能最终将一个View绘制出来。测试
一个32为的int值,高2位表明SpecMode 低30位表明SpecSize。ui
DecorView 其MeasureSpec是由自身的LayoutParams和窗口的尺寸来共同决定spa
普通的View 其MeasureSpec是由父容器的MeasureSpec和自身的LayoutParams来共同决定code
简单来讲自定义Veiw到measure这一步的时候,须要测试自身的宽高,须要widthMeasureSpec, heightMeasureSpec,宽的测量规格和高的测量规格,二者的获取方式都是同样,须要根据父容器的MeasureSpec 和自身的 宽高来获得。orm
View的measure过程,到这一步确定是通过了父控件的measure过程,获得了父控件传下来的measureSpec,而后调用onMeasure,经过setMeasuredDimension 来肯定自身的宽高。固然中间须要通过一些计算获得widthMeasureSpec, heightMeasureSpec。cdn
Activity/View#onWindowFocusChanged。
ViewTreeObserver.addOnGlobalLayoutListener()。
从ViewRootImpl的构造方法中调用 loadSystemProperties()
->profileRendering()
->scheduleTraversals()
-> mChoreographer.postCallback(Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);
->doTraversal();
->performTraversals();
->performMeasure(childWidthMeasureSpec, childHeightMeasureSpec);
-> performLayout(lp, mWidth, mHeight);
-> performDraw();
完成View的三大流程。