View的工作流程指的就是measure、layout和draw。其中measure用来测量VIew的宽和高,layout用来确定View的位置,draw用来绘制View。

Acitivity启动过程

startActivityForResult方法

先从Activity的startActivity方法说起。

startActivity方法或startActivityForResult有很多种重载方式,但它们最终都会调用startActivityForResult(intent, requestCode, options)方法。源码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
@Nullable Bundle options) {

//如果是第一次启动,则成员变量mParent为空,否则不为空。
if (mParent == null) {
//第一次启动执行
options = transferSpringboardActivityOptions(options);

//调用Instrumentation的execStartActivity(Context who, IBinder contextThread····)方法

Instrumentation.ActivityResult ar = mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this, intent, requestCode, options);
if (ar != null) {
mMainThread.sendActivityResult(
mToken, mEmbeddedID, requestCode, ar.getResultCode(),ar.getResultData());
}
if (requestCode >= 0) {
// 如果是请求一个结果(result),我们可以使Activity不可见,直到收到结果,在onCreate(Bundle savedInstanceState)方法或者onResume()期间设置此代码将在此期间隐藏Activity,以避免闪烁,只有在请求结果时才可以这样做,因为这样可以保证在Activity完成时我们将获得信息,无论它发生了什么

mStartedActivity = true;
}

cancelInputsAndStartExitTransition(options);
} else {
//如果不是第一次启动执行
if (options != null) {
mParent.startActivityFromChild(this, intent, requestCode, options);
} else {
mParent.startActivityFromChild(this, intent, requestCode);
}
}
}

Instrumentation的execStartActivity方法

我们来看一看第一次执行时调用的Instrumentation的execStartActivity(Context who, IBinder contextThread, IBinder token, Activity target, Intent intent, int requestCode, Bundle options)方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//Instrumentation.java

@UnsupportedAppUsage
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
// 省略部分代码
try {
intent.migrateExtraStreamToClipData(who);
intent.prepareToLeaveProcess(who);
// 调用ActivityTaskManagerService的startActivity方法
int result = ActivityTaskManager.getService()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, options);
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
return null;
}

ActivityTaskManager.getService()方法得到的是IActivityTaskManager接口,它是通过进程间通讯(Inter-Process Communication,即IPC)调用的,IActivityTaskManager服务端ActivityTaskManagerService,所以最终是调用ActivityTaskManagerServicestartActivity方法,后面的调用过程,这里就不再详细地讲解,最后调用的是ActivityThread类的**handleLaunchActivity(ActivityClientRecord r, PendingTransactionActions pendingActions, Intent customIntent)**方法,

调用的是ActivityThread类的handleLaunchActivity方法

源码如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
@Override
public Activity handleLaunchActivity(ActivityClientRecord r,
PendingTransactionActions pendingActions, Intent customIntent) {
// If we are getting ready to gc after going to the background, well
// we are back active so skip it.
unscheduleGcIdler();
mSomeActivitiesChanged = true;

if (r.profilerInfo != null) {
mProfiler.setProfiler(r.profilerInfo);
mProfiler.startProfiling();
}

// Make sure we are running with the most recent config.
handleConfigurationChanged(null, null);

if (localLOGV) Slog.v(
TAG, "Handling launch of " + r);

// Initialize before creating the activity
if (!ThreadedRenderer.sRendererDisabled
&& (r.activityInfo.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0) {
HardwareRenderer.preload();
}

//----------------------从这里开始-------------------------//

WindowManagerGlobal.initialize(); // 初始化全局的WindowManagerGlobal

// Hint the GraphicsEnvironment that an activity is launching on the process. 提示图形环境Activity正在进程上启动.
GraphicsEnvironment.hintActivityLaunch();

final Activity a = performLaunchActivity(r, customIntent); //1

if (a != null) {
r.createdConfig = new Configuration(mConfiguration);
reportSizeConfigurations(r);
if (!r.activity.mFinished && pendingActions != null) {
pendingActions.setOldState(r.state);
pendingActions.setRestoreInstanceState(true);
pendingActions.setCallOnPostCreate(true);
}
} else {
// If there was an error, for any reason, tell the activity manager to stop us.
try {
ActivityTaskManager.getService()
.finishActivity(r.token, Activity.RESULT_CANCELED, null,
Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}

return a;
}

调用performLaunchActivity方法来创建Activity

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
/**  Core implementation of activity launch. */
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
//一些需要启动的Activity的信息。
ActivityInfo aInfo = r.activityInfo;
if (r.packageInfo == null) {
r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
Context.CONTEXT_INCLUDE_CODE);
}

ComponentName component = r.intent.getComponent();
if (component == null) {
component = r.intent.resolveActivity(
mInitialApplication.getPackageManager());
r.intent.setComponent(component);
}

if (r.activityInfo.targetActivity != null) {
component = new ComponentName(r.activityInfo.packageName,
r.activityInfo.targetActivity);
}

ContextImpl appContext = createBaseContextForActivity(r);
Activity activity = null;
try {
java.lang.ClassLoader cl = appContext.getClassLoader();
// 反射创建Activity
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
StrictMode.incrementExpectedActivityCount(activity.getClass());
r.intent.setExtrasClassLoader(cl);
r.intent.prepareToEnterProcess();
if (r.state != null) {
r.state.setClassLoader(cl);
}
} catch (Exception e) {
if (!mInstrumentation.onException(activity, e)) {
throw new RuntimeException(
"Unable to instantiate activity " + component
+ ": " + e.toString(), e);
}
}

try {
// 创建Application对象,它是个单例,一个进程只有一个Application
Application app = r.packageInfo.makeApplication(false, mInstrumentation);

// 省略部分代码

if (activity != null) {
// 省略部分代码

// Activity resources must be initialized with the same loaders as the
// application context.
appContext.getResources().addLoaders(
app.getResources().getLoaders().toArray(new ResourcesLoader[0]));

appContext.setOuterContext(activity);

// Activity成功创建,调用Activity的attach方法,这个方法会创建PhoneWindow,它是Window抽象类的子类
// 将 context等各种数据与Activity绑定,初始化Activity
activity.attach(appContext, this, getInstrumentation(), r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embeddedID, r.lastNonConfigurationInstances, config,
r.referrer, r.voiceInteractor, window, r.configCallback,
r.assistToken);

// 省略部分代码
// 调用Activity的onCreate方法
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
if (!activity.mCalled) {
throw new SuperNotCalledException(
"Activity " + r.intent.getComponent().toShortString() +
" did not call through to super.onCreate()");
}
r.activity = activity;
}
// 设为ON_CREATE状态
r.setState(ON_CREATE);

// updatePendingActivityConfiguration()方法的作用是从mActivities中读取数据以更新ActivityClientRecord,它在不同的线程中运行,所以要取ResourcesManager作为锁对象
synchronized (mResourcesManager) {
mActivities.put(r.token, r);
}

} catch (SuperNotCalledException e) {
throw e;

} catch (Exception e) {
if (!mInstrumentation.onException(activity, e)) {
throw new RuntimeException(
"Unable to start activity " + component
+ ": " + e.toString(), e);
}
}

// 返回Activity
return activity;
}

performActivity通过反射机制创建了Activity的实例,并且构建了Application的实例。

调用了Activity的attach方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
//Activity.java
@UnsupportedAppUsage
final void attach(Context context, ActivityThread aThread,
Instrumentation instr, IBinder token, int ident,
Application application, Intent intent, ActivityInfo info,
CharSequence title, Activity parent, String id,
NonConfigurationInstances lastNonConfigurationInstances,
Configuration config, String referrer, IVoiceInteractor voiceInteractor,
Window window, ActivityConfigCallback activityConfigCallback, IBinder assistToken) {
// 省略部分代码

// 创建PhoneWindow对象,并且赋值给成员变量mWindow
mWindow = new PhoneWindow(this, window, activityConfigCallback);
mWindow.setWindowControllerCallback(mWindowControllerCallback);
mWindow.setCallback(this);
mWindow.setOnWindowDismissedCallback(this);
mWindow.getLayoutInflater().setPrivateFactory(this);

// .....

// 将Window和WindowManager绑定
mWindow.setWindowManager(
(WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
mToken, mComponent.flattenToString(),
(info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);

// 省略部分代码
}

调用了Instrumentation对象的callActivityOnCreate方法

1
2
3
4
5
public void callActivityOnCreate(Activity activity, Bundle icicle,PersistableBundle persistentState) {
prePerformCreate(activity);
activity.performCreate(icicle, persistentState);
postPerformCreate(activity);
}

调用了Activity的preformCreate方法

1
2
3
4
5
6
7
8
9
10
11
final void performCreate(Bundle icicle, PersistableBundle persistentState) {
dispatchActivityPreCreated(icicle);
mCanEnterPictureInPicture = true;
restoreHasCurrentPermissionRequest(icicle);
if (persistentState != null) {
onCreate(icicle, persistentState);
} else {
onCreate(icicle);
}
.......
}

调用了创建好的Activity的onCreate方法,至此,Activity启动完成。

调用OnStart和OnResume执行绘制流程

接着前面的逻辑,接着就会调用ActivityThread类的handleStartActivity(ActivityClientRecord r, PendingTransactionActions pendingActions)方法,然后Activity类的onStart方法就会被调用,然后调用ActivityThread类的**handleResumeActivity(IBinder token, boolean finalStateRequest, boolean isForward, String reason)**方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
//ActivityThread.java
@Override
public void handleResumeActivity(IBinder token, boolean finalStateRequest, boolean isForward,
String reason) {
// 省略部分代码

// 调用Activity的onResume方法
final ActivityClientRecord r = performResumeActivity(token, finalStateRequest, reason);
// 省略部分代码

final Activity a = r.activity;

// 省略部分代码
if (r.window == null && !a.mFinished && willBeVisible) {
// 得到Window,Window是抽象类,其中,PhoneWindow类继承Window类,它是Window类的唯一子类
r.window = r.activity.getWindow();
// 得到DecorView
View decor = r.window.getDecorView();
// 将DecorView设为不可见
decor.setVisibility(View.INVISIBLE);
// 得到ViewManager,ViewManager是一个接口,WindowManger也是一个接口,它继承ViewManager接口,其中,WindowManagerImpl类实现ViewManager接口,这里的vm可以看作是WindowMangerImpl对象
ViewManager wm = a.getWindowManager();
WindowManager.LayoutParams l = r.window.getAttributes();
// 省略部分代码
if (a.mVisibleFromClient) {
if (!a.mWindowAdded) {
a.mWindowAdded = true;
// 调用WindowManagerImpl类的addView(View view, ViewGroup.LayoutParams params)方法,执行绘制流程
wm.addView(decor, l);//decorView 和 PhoneWindow 的布局参数
} else {
// 省略部分代码
}
}

} else if (!willBeVisible) {
// 如果Window已经被添加,但是在恢复(resume)期间启动了另一个Activity,这样的话,就不要使Window可见
if (localLOGV) Slog.v(TAG, "Launch " + r + " mStartedActivity set");
r.hideForNow = true;
}

// 省略部分代码
}

ActivityThread#handleResumeActivity方法首先调用performResumeActivity,在performResumeActivity完成之后在会调用WindowManager#addView向Window中添加布局。 所以,实际上布局是在onResume完成之后才被加载在PhoneWindow中的,不过具体的内容我们还是需要看看performResumeActivity

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public ActivityClientRecord performResumeActivity(IBinder token, boolean finalStateRequest,
String reason) {
final ActivityClientRecord r = mActivities.get(token);
// 对于Lifecycle的一些判断
if (r.getLifecycleState() == ON_RESUME) {
if (!finalStateRequest) {
// ... 如果已经是onResume 就回抛出异常
}
return null;
}

// ....

try {
// ...

// 调用Activity#performResume 调用流程同上onCreate,最终会调用activity的onResume。
r.activity.performResume(r.startsNotResumed, reason);

r.state = null;
r.persistentState = null;
r.setState(ON_RESUME);

reportTopResumedActivityChanged(r, r.isTopResumedActivity, "topWhenResuming");
} catch (Exception e) {
// ....
}
return r;
}

View的绘制流程 在Activity的onResume方法之后执行

调用WindowManagerImpl类的addView方法

调用WindowManagerImpl类的addView(View view, ViewGroup.LayoutParams params)方法分别传入了DecorViewPhoneWindow的属性

1
2
3
4
5
6
7
8
9
10
11
12
13
public final class WindowManagerImpl implements WindowManager {
@UnsupportedAppUsage
private final WindowManagerGlobal mGlobal = WindowManagerGlobal.getInstance();
//···

@Override
public void addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {
applyDefaultToken(params);
//decorView 和 PhoneWindow 的布局参数
mGlobal.addView(view, params, mContext.getDisplayNoVerify(), mParentWindow,mContext.getUserId());
}
//···
}

调用了WindowManagerGlobal类的addView方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
//WindowManagerGlobal.java
public void addView(View view, ViewGroup.LayoutParams params,
Display display, Window parentWindow) {
//···

final WindowManager.LayoutParams wparams = (WindowManager.LayoutParams) params;
// 省略部分代码

ViewRootImpl root;
View panelParentView = null;

synchronized (mLock) {
// 省略部分代码

// 创建ViewRootImpl对象
root = new ViewRootImpl(view.getContext(), display);

// 设置DecorView的LayoutParams
view.setLayoutParams(wparams);

// 将DecorView添加到View的ArrayList中
mViews.add(view);
// 将ViewRootImpl添加到ViewRootImpl的ArrayList中
mRoots.add(root);
// 将DecorView的LayoutParams添加到WindowManager.LayoutParams的ArrayList中
mParams.add(wparams);

try {
//调用ViewRootImpl的setView(View view, WindowManager.LayoutParams attrs, View panelParentView)方法
root.setView(view, wparams, panelParentView);//decorView 和 PhoneWindow 的布局参数,NULL
} catch (RuntimeException e) {
// 抛出BadTokenException或者InvalidDisplayException
if (index >= 0) {
removeViewLocked(index, true);
}
throw e;
}
}
}

调用了ViewRootImpl类的setView方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
//ViewRootImpl.java
public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {
synchronized (this) {
if (mView == null) {
// 如果成员变量mView为空,就将传进来的DecorView赋值给它
mView = view;

// 省略部分代码
// 调用requestLayout()方法
requestLayout();
// 省略部分代码
try {
mOrigWindowType = mWindowAttributes.type;
mAttachInfo.mRecomputeGlobalAttributes = true;
collectViewAttributes();
adjustLayoutParamsForCompatibility(mWindowAttributes);
//调用WindowSession#addToDispaly,再调用WindowManagerService#addWindow
res = mWindowSession.addToDisplayAsUser(mWindow, mSeq, mWindowAttributes,
getHostVisibility(), mDisplay.getDisplayId(), userId, mTmpFrame,
mAttachInfo.mContentInsets, mAttachInfo.mStableInsets,
mAttachInfo.mDisplayCutout, inputChannel,
mTempInsets, mTempControls);
setFrame(mTmpFrame);
} catch {
//···
}
//···

// 调用View的assignParent(ViewParent parent)方法
view.assignParent(this);
// 省略部分代码
}
}
}

requestLayout方法

1
2
3
4
5
6
7
8
@Override
public void requestLayout() {
if (!mHandlingLayoutInLayoutRequest) {
checkThread();
mLayoutRequested = true;
scheduleTraversals();
}
}

requestLayout()方法的作用是检查当前线程是不是创建ViewRootImpl所在的线程如果是就通知View执行绘制流程否则就抛出CalledFromWrongThreadException异常

View的assignParent方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//View.java
@UnsupportedAppUsage
void assignParent(ViewParent parent) {
if (mParent == null) {
// 如果这个View还没有parent,就将传进来的ViewRootImpl赋值给成员变量mParent
mParent = parent;
} else if (parent == null) {
// 如果形式参数parent为空,就将成员变量mParent设为空
mParent = null;
} else {
// 如果这个View已经有parent,再次设置parent就会抛出RuntimeException异常
throw new RuntimeException("view " + this + " being added, but"
+ " it already has a parent");
}
}

这个方法的作用是将ViewRootImpl和DecorView关联起来,这里传进来的是ViewRootImplViewRootImpl实现ViewParent接口,每一个Activity根布局DecorViewDecorViewparentViewViewRootImpl,所以在子元素中调用invalidate()方法这类的方法的时候,需要遍历找到parentView,最后都会调用ViewRootImpl相关的方法。

5bSGWV.jpg

setContentView方法

我们的Activity类是继承AppCompatActivity类.

Appcompat最开始是出现在com.android.support:appcompat-v7库中,它是为了让Android SDK 7(Android 2.1,即Android Eclair)以上的设备可以使用ActionBar,而在com.android.support:appcompat-v7:21以上的库,AppCompat可以为Android SDK 7(Android 2.1,即Android Eclair)以上的设备带来Material Color PaletteWidget着色Toolbar等功能,并且用AppCompatActivity替代ActionBarActivity,在Android SDK 28(Android 9.0,即Android Pie)发布后,appcompat库都迁移到了AndroidX库,AndroidX库是Android Jetpack组件。

AppCompatActivity类的setContentView方法

1
2
3
4
5
6
// AppCompatActivity.java
@Override
public void setContentView(@LayoutRes int layoutResID) {
// 调用AppCompatDelegate的setContentView(int resId)方法
getDelegate().setContentView(layoutResID);
}

getDelegate方法

1
2
3
4
5
6
7
8
9
10
// AppCompatActivity.java
@NonNull
public AppCompatDelegate getDelegate() {
if (mDelegate == null) {
// 如果mDelegate为空,就调用AppCompatDelegate抽象类的create(@NonNull Activity activity, @Nullable AppCompatCallback callback)方法
mDelegate = AppCompatDelegate.create(this, this);
}
return mDelegate;
}

AppCompatDelegate抽象类的create方法

1
2
3
4
5
6
7
// AppCompatDelegate.java
@NonNull
public static AppCompatDelegate create(@NonNull Activity activity,
@Nullable AppCompatCallback callback) {
// 创建AppCompatDelegateImpl对象
return new AppCompatDelegateImpl(activity, callback);
}

所以AppCompatDelegateImpl类是继承AppCompatDelegate抽象类。

AppCompatDelegateImpl的setContentView方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// AppCompatDelegateImpl.java
@Override
public void setContentView(int resId) {
// 创建DecorView,并且将其添加到Window
ensureSubDecor();
// 找到DecorView中的contentView
ViewGroup contentParent = mSubDecor.findViewById(android.R.id.content);
// 移除contentView中所有的View
contentParent.removeAllViews();
// 根据传入的resId将要加载的XML布局添加到contentView
LayoutInflater.from(mContext).inflate(resId, contentParent);
// onContentChanged()方法是一个钩子方法,它会在屏幕的内容视图发生变化时调用
mAppCompatWindowCallback.getWrapped().onContentChanged();
}

ensureSubDecor方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
// AppCompatDelegateImpl.java
private void ensureSubDecor() {
if (!mSubDecorInstalled) {
// 如果还没有创建DecorView,就调用createSubDecor()方法创建DecorView
mSubDecor = createSubDecor();

// 得到title的字符
CharSequence title = getTitle();
if (!TextUtils.isEmpty(title)) {
// 如果设置了title,就执行以下逻辑
if (mDecorContentParent != null) {
mDecorContentParent.setWindowTitle(title);
} else if (peekSupportActionBar() != null) {
peekSupportActionBar().setWindowTitle(title);
} else if (mTitleView != null) {
mTitleView.setText(title);
}
}
//适配尺寸在设备上,一些参数的初始化
applyFixedSizeWindow();

onSubDecorInstalled(mSubDecor);

// 标记已经创建DecorView
mSubDecorInstalled = true;

// 创建面板菜单
PanelFeatureState st = getPanelState(FEATURE_OPTIONS_PANEL, false);
if (!mIsDestroyed && (st == null || st.menu == null)) {
// 通过添加刷新通知消息到主线程对应的消息队列中来刷新界面,目的是防止onCreateOptionsMenu(Nenu menu)方法在Activity调用onCreate(@Nullable Bundle savedInstanceState)方法的途中被调用
invalidatePanelMenu(FEATURE_SUPPORT_ACTION_BAR);
}
}
}

作用是创建DecorView并且将其添加到Window中同时创建面板菜单

createSubDecor方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
// AppCompatDelegateImpl.java
private ViewGroup createSubDecor() {
TypedArray a = mContext.obtainStyledAttributes(R.styleable.AppCompatTheme);

if (!a.hasValue(R.styleable.AppCompatTheme_windowActionBar)) {
a.recycle();
// 如果使用AppCompatActivity,但是没有设置一个Theme.AppCompat的主题,就抛出IllegalStateException异常
throw new IllegalStateException(
"You need to use a Theme.AppCompat theme (or descendant) with this activity.");
}

// 设置Window的属性
if (a.getBoolean(R.styleable.AppCompatTheme_windowNoTitle, false)) {
requestWindowFeature(Window.FEATURE_NO_TITLE);
} else if (a.getBoolean(R.styleable.AppCompatTheme_windowActionBar, false)) {
// 不允许没有标题的actionBar
requestWindowFeature(FEATURE_SUPPORT_ACTION_BAR);
}
if (a.getBoolean(R.styleable.AppCompatTheme_windowActionBarOverlay, false)) {
requestWindowFeature(FEATURE_SUPPORT_ACTION_BAR_OVERLAY);
}
if (a.getBoolean(R.styleable.AppCompatTheme_windowActionModeOverlay, false)) {
requestWindowFeature(FEATURE_ACTION_MODE_OVERLAY);
}
mIsFloating = a.getBoolean(R.styleable.AppCompatTheme_android_windowIsFloating, false);
a.recycle();

// 调用ensureWindow()方法来检查DecorView是否已经添加到Window
ensureWindow();
// 调用成员变量mWindow的getDecorView()方法创建DecorView,要注意的是,成员变量mWindow声明为Window,Window是一个抽象类,这里的实现类是PhoneWindow
mWindow.getDecorView();

// 得到LayoutInflater
final LayoutInflater inflater = LayoutInflater.from(mContext);
ViewGroup subDecor = null;


// 根据标志添加到对应的布局
if (!mWindowNoTitle) {
if (mIsFloating) {
// 如果窗口需要浮动,就添加id是abc_dialog_title_material的布局
subDecor = (ViewGroup) inflater.inflate(
R.layout.abc_dialog_title_material, null);

// 浮动窗口不能有操作栏,重置标志
mHasActionBar = mOverlayActionBar = false;
} else if (mHasActionBar) {
// 如果窗口有actionBar,就执行以下逻辑
TypedValue outValue = new TypedValue();
mContext.getTheme().resolveAttribute(R.attr.actionBarTheme, outValue, true);

Context themedContext;
if (outValue.resourceId != 0) {
themedContext = new ContextThemeWrapper(mContext, outValue.resourceId);
} else {
themedContext = mContext;
}

// 使用主题化上下文(themedContext)添加id是abc_screen_toolbar的布局
subDecor = (ViewGroup) LayoutInflater.from(themedContext)
.inflate(R.layout.abc_screen_toolbar, null);

mDecorContentParent = (DecorContentParent) subDecor
.findViewById(R.id.decor_content_parent);
mDecorContentParent.setWindowCallback(getWindowCallback());

// 将特性传给DecorContentParent
if (mOverlayActionBar) {
mDecorContentParent.initFeature(FEATURE_SUPPORT_ACTION_BAR_OVERLAY);
}
if (mFeatureProgress) {
mDecorContentParent.initFeature(Window.FEATURE_PROGRESS);
}
if (mFeatureIndeterminateProgress) {
mDecorContentParent.initFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
}
}
} else {
if (mOverlayActionMode) {
// 如果需要覆盖Activity的内容,就添加id是abc_screen_simple_overlay_action_mode的布局
subDecor = (ViewGroup) inflater.inflate(
R.layout.abc_screen_simple_overlay_action_mode, null);
} else {
// 如果不需要覆盖Activity的内容,就添加id是abc_screen_simple的布局
subDecor = (ViewGroup) inflater.inflate(R.layout.abc_screen_simple, null);
}

// 省略部分代码
}

if (subDecor == null) {
// 如果DecorView这个时候还是空,就抛出IllegalArgumentException异常
throw new IllegalArgumentException(
"AppCompat does not support the current theme features: { "
+ "windowActionBar: " + mHasActionBar
+ ", windowActionBarOverlay: "+ mOverlayActionBar
+ ", android:windowIsFloating: " + mIsFloating
+ ", windowActionModeOverlay: " + mOverlayActionMode
+ ", windowNoTitle: " + mWindowNoTitle
+ " }");
}

if (mDecorContentParent == null) {
// 如果成员变量mDecorContentParent为空,就将DecorView中的id为title的TextView赋值给成员变量mTitleView
mTitleView = (TextView) subDecor.findViewById(R.id.title);
}

// 让装饰可以选择适合系统窗口,例如:Window的装饰
ViewUtils.makeOptionalFitsSystemWindows(subDecor);

final ContentFrameLayout contentView = (ContentFrameLayout) subDecor.findViewById(
R.id.action_bar_activity_content);

// 得到contentView
final ViewGroup windowContentView = (ViewGroup) mWindow.findViewById(android.R.id.content);
if (windowContentView != null) {
while (windowContentView.getChildCount() > 0) {
// 如果已经有View添加到Window的contentView,就把它们迁移到contentView
final View child = windowContentView.getChildAt(0);
windowContentView.removeViewAt(0);
contentView.addView(child);
}

windowContentView.setId(View.NO_ID);
// 给contentView添加android.R.id.content的id,对Fragment挺有用
contentView.setId(android.R.id.content);

// decorContent有一个前景可绘制的设置(windowContentOverlay),设为空,是因为我们自己处理它
if (windowContentView instanceof FrameLayout) {
((FrameLayout) windowContentView).setForeground(null);
}
}

// 调用PhoneWindow的setContentView(View view)方法
mWindow.setContentView(subDecor);

contentView.setAttachListener(new ContentFrameLayout.OnAttachListener() {
@Override
public void onAttachedFromWindow() {}

@Override
public void onDetachedFromWindow() {
dismissPopups();
}
});

// 返回DecorView
return subDecor;
}

参考文章及资料:
《Android进阶之光》 //这本书的代码是之前的版本了,有的东西已经过时。

深入了解Android的View工作原理:https://www.jianshu.com/p/4361fe3cf287

Android UI体系知识&面试题: https://www.bilibili.com/read/cv13672159?spm_id_from=333.999.0.0