創(chuàng)建window過(guò)程
當(dāng)我們調(diào)用startActivity方法之后系統(tǒng)會(huì)通過(guò)AMS等一系列的方法最后調(diào)用ActivityThread的performLaunchActivity方法,在方法里會(huì)調(diào)用attach方法
在Activity的attach方法里面系統(tǒng)會(huì)初始化Window的實(shí)現(xiàn)類PhoneWindow并通過(guò)setWindowManager方法創(chuàng)建mWindowManager的實(shí)現(xiàn)類WindowManagerImpl
setContentView過(guò)程
創(chuàng)建完之后ActivityThread會(huì)繼續(xù)執(zhí)行performLaunchActivity方法調(diào)用Instrumentation的callActivityOnCreate方法独悴,然后會(huì)調(diào)用activity的OnCreate
然后我們?cè)贠nCreate里面調(diào)用setContentView,點(diǎn)進(jìn)去可以看到是調(diào)用Window的setContentView方法损合,從前一步我們知道其實(shí)就是調(diào)用的window的實(shí)現(xiàn)類PhoneWindow的setContentView
PhoneWindow的setContentView方法源碼
在這個(gè)方法里面會(huì)初始化DecorView然后將我們xml的布局文件轉(zhuǎn)換成View最后加到DecorView的id為content的FrameLayout上
View的繪制
之后ActivityThread會(huì)繼續(xù)執(zhí)行handleResumeActivity方法里面會(huì)調(diào)用performResumeActivity調(diào)用完就會(huì)執(zhí)行Activity的onResume方法之后繼續(xù)走才開(kāi)始View的繪制所以View的繪制是在Activity生命周期onResume之后的
@Override
public void handleResumeActivity(IBinder token, boolean finalStateRequest, boolean isForward,
String reason) {
//調(diào)用Activity的onResume
final ActivityClientRecord r = performResumeActivity(token, finalStateRequest, reason);
if (r.window == null && !a.mFinished && willBeVisible) {
r.window = r.activity.getWindow();
View decor = r.window.getDecorView();
decor.setVisibility(View.INVISIBLE);
ViewManager wm = a.getWindowManager();
WindowManager.LayoutParams l = r.window.getAttributes();
a.mDecor = decor;
l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
l.softInputMode |= forwardBit;
if (r.mPreserveWindow) {
a.mWindowAdded = true;
r.mPreserveWindow = false;
ViewRootImpl impl = decor.getViewRootImpl();
if (impl != null) {
impl.notifyChildRebuilt();
}
}
if (a.mVisibleFromClient) {
if (!a.mWindowAdded) {
a.mWindowAdded = true;
//調(diào)用ViewManager的實(shí)現(xiàn)類WindowManagerImpl window創(chuàng)建的時(shí)候有提到
wm.addView(decor, l);
} else {
a.onWindowAttributesChanged(l);
}
}
} else if (!willBeVisible) {
if (localLOGV) Slog.v(TAG, "Launch " + r + " mStartedActivity set");
r.hideForNow = true;
}
}
然后會(huì)執(zhí)行WindowManagerImpl的addView方法
WindowManagerImpl是通過(guò)WindowManagerGlobal的addView方法
WindowManagerGlobal的addView方法
在addView方法里面會(huì)創(chuàng)建ViewRootImpl它是連接WindowManager和DecorView的紐帶验庙,View的繪制流程就是通過(guò)ViewRootImpl實(shí)現(xiàn)的袜刷,通過(guò)root.setView(view, wparams, panelParentView);
View的繪制流程
在setView方法中會(huì)調(diào)用requestLayout()
其中checkThread檢測(cè)是否在主線程不是會(huì)拋出異常所以更新UI必須在主線程就是在這里控制額
然后調(diào)用scheduleTraversals()通過(guò)方法里面的mTraversalRunnable的run執(zhí)行doTraversal
繼續(xù)調(diào)用doTraversal方法里面的performTraversals()在performTraversals()方法里面會(huì)依次調(diào)用View的performMeasure议经,performLayout横堡,performDraw在各自的方法里面會(huì)調(diào)用對(duì)應(yīng)的的View的measure埋市,layout,draw在然后就會(huì)走View的onMeasure命贴,onLayout恐疲,onDraw腊满,至此View的繪制完成Acticity就會(huì)展示我們的頁(yè)面