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的三大流程。