Android-Activity启动流程

Android-Activity启动流程

1. Activity启动入口

操作系统启动后,第一个启动的就是 init 进程,init 进程会启动 ZygoteServiceManager 等基本进程。随后 Zygot 创建并初始化 system_service,system_service 会分裂出 AMS 等各项系统服务。当启动一个 App 时,实际流程是:

  • Launcher 通过 IPC 通知 AMS。
  • AMS 通知 system_service。
  • system_service 通知 Zygote。
  • Zygote 收到通知后 Fork 出子进程。
  • 子进程在 Process#start() 中通过反射调用 ActivityThread.main()

App 进程的入口在 ActivityThread#main(),包括初始化操作系统、用户环境、启动主线程 Looper 等。ActivityThread$ActivityClientRecord 以容器的形式持有了一个 Activity,以及管理这个 Activity 相关的其他资源,并且与持有的 Activity 是一一对应的,系统大多都是通过 ActivityClientRecord 操作 Activity 来管理和调度 Activity。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public final class ActivityThread extends ClientTransactionHandler {
/** Activity client record, used for bookkeeping for the real {@link Activity} instance. */
public static final class ActivityClientRecord {
Activity activity;
Window window;
Activity parent;
}

public static void main(String[] args) {
Looper.prepareMainLooper();
ActivityThread thread = new ActivityThread();
thread.attach(false, startSeq);
}
}

启动一个 Activity 的入口,在 API 29 开始与之前版本有不同。在 API 29 之前的版本,ActivityThread 内部持有的一个 Handler 对象 H 监听了 LAUNCH_ACTIVITY 事件,并在收到 LAUNCH_ACTIVITY 请求后会调用 handleLaunchActivity(...)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
private class H extends Handler {
public void handleMessage(Message msg) {
switch (msg.what) {
// API 29 移除了 LAUNCH_ACTIVITY 这个条件分支,
// 而是放在 BIND_APPLICATION 中处理。
case LAUNCH_ACTIVITY: {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
final ActivityClientRecord r = (ActivityClientRecord) msg.obj;

r.packageInfo = getPackageInfoNoCheck(
r.activityInfo.applicationInfo, r.compatInfo);
handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
}
}
}
}

但在 API 29 以上版本已经移除了这个分支,下文基于 API 29 分析。

1.1 ActivityThread初始化

首先在入口方法 ActivityThread#main() 中,有一个关键步骤 thread.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
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
public final class ActivityThread extends ClientTransactionHandler {

// 内部类 ApplicationThread 继承自 AIDL 类 IApplicationThread#Stub
final ApplicationThread mAppThread = new ApplicationThread();

private void attach(boolean system, long startSeq) {
if (!system) {
// mgr 就是 AMS 的远程 AIDL 接口
final IActivityManager mgr = ActivityManager.getService();
try {
mgr.attachApplication(mAppThread, startSeq);
}
}
}
}

public class ActivityManagerService extends IActivityManager.Stub
implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {

// ActivityTaskManagerInternal 抽象类只有一个实现类:ActivityTaskManagerService$LocalService
public ActivityTaskManagerInternal mAtmInternal;

public final void attachApplication(IApplicationThread thread, long startSeq) {
synchronized (this) {
attachApplicationLocked(thread, callingPid, callingUid, startSeq);
}
}

private final boolean attachApplicationLocked(IApplicationThread thread,
int pid, int callingUid, long startSeq) {
try {
// AMS 通过 ApplicationThread 这个 AIDL Proxy 和 App 进程的 ActivityThread 通信
if (app.isolatedEntryPoint != null) {
// This is an isolated process which should just call an entry point instead of being bound to an application.
thread.runIsolatedEntryPoint(...);
} else if (instr2 != null) {
thread.bindApplication(...);
} else {
thread.bindApplication(...);
}
}
// 尝试启动 Activity
// See if the top visible activity is waiting to run in this process...
if (normalMode) {
try {
didSomething = mAtmInternal.attachApplication(app.getWindowProcessController());
} catch (Exception e) {
Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
badApp = true;
}
}
}
}

可以看到 AMS 调用 attachApplication(...) 后主要分为两个步骤:

  • 调用 ActivityThread$ApplicationThread#bindApplication(...)
  • 调用 ActivityTaskManagerService$LocalService#attachApplication(...)

1.2 创建和绑定Application

AMS#attachApplication(...) 内第 1 步执行 ApplicationThread.bindApplication(...)

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
public final class ActivityThread extends ClientTransactionHandler {

private class ApplicationThread extends IApplicationThread.Stub {
public final void bindApplication(...) {
// AppBindData 提供绑定 Application 对象的信息,例如 Process, Instrumentation, AppInfo 等。
AppBindData data = new AppBindData();
// 向 ActivityThread 的 Handler 发送了一条 BIND_APPLICATION 请求,回到 App 进程
sendMessage(H.BIND_APPLICATION, data);
}
}

private class H extends Handler {
public void handleMessage(Message msg) {
case BIND_APPLICATION: {
AppBindData data = (AppBindData)msg.obj;
handleBindApplication(data);
break;
}
}
}

private void handleBindApplication(AppBindData data) {
// 回调 Application#onCreate()
mInstrumentation.callApplicationOnCreate(app);
}
}

1.3 进入Activity启动事务

AMS#attachApplication(...) 内第 2 步执行 mAtmInternal.attachApplication(...),是启动 Activity 的起点。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class ActivityTaskManagerService extends IActivityTaskManager.Stub {

final class LocalService extends ActivityTaskManagerInternal {
public boolean attachApplication(WindowProcessController wpc) throws RemoteException {
synchronized (mGlobalLockWithoutBoost) {
return mRootActivityContainer.attachApplication(wpc);
}
}
}
}

class RootActivityContainer extends ConfigurationContainer
implements DisplayManager.DisplayListener {

ActivityStackSupervisor mStackSupervisor;

boolean attachApplication(WindowProcessController app) throws RemoteException {
// 结束 Application 启动流程,正式进入 Activity 启动流程
if (mStackSupervisor.realStartActivityLocked(activity, app,
top == activity /* andResume */, true /* checkConfig */)) {
}
}
}

1.3.1 初始化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
public class ActivityStackSupervisor implements RecentTasks.Callbacks {
boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
boolean andResume, boolean checkConfig) throws RemoteException {
// 传入的 proc.getThread 就是 IApplicationThread
// Create activity launch transaction.
final ClientTransaction clientTransaction = ClientTransaction.obtain(
proc.getThread(), r.appToken);
// 注意入参是 LaunchActivityItem 对象
clientTransaction.addCallback(LaunchActivityItem.obtain(...));
// Set desired final state.
final ActivityLifecycleItem lifecycleItem;
// 如果是 App 启动则 andResume == true,表示需要让首个 Activity 进入 Resume 状态
if (andResume) {
lifecycleItem = ResumeActivityItem.obtain(dc.isNextTransitionForward());
} else {
lifecycleItem = PauseActivityItem.obtain();
}
clientTransaction.setLifecycleStateRequest(lifecycleItem);

// mService 是 ClientLifecycleManager 对象
// Schedule transaction.
mService.getLifecycleManager().scheduleTransaction(clientTransaction);
......
}
}

ActivityStackSupervisor 生成了一个 ClientTransaction 对象,用于记录客户端要处理的事务(也就是 Activity 启动):

  • 给 ClientTransaction 添加 Callback,传入 LaunchActivityItem 类型的对象。
  • 给 ClientTransaction 设置生命周期状态流转请求,传入 ResumeActivityItem 类型的对象,表示目标是流转到 onResume 状态。
  • 调用 ClientLifecycleManager#scheduleTransaction 提交 ClientTransaction 启动事务。

1.3.2 提交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
class ClientLifecycleManager {
void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
final IApplicationThread client = transaction.getClient();
transaction.schedule();
}
}

public class ClientTransaction implements Parcelable, ObjectPoolItem {

private IApplicationThread mClient;

/** Obtain an instance initialized with provided params. */
public static ClientTransaction obtain(IApplicationThread client, IBinder activityToken) {
ClientTransaction instance = ObjectPool.obtain(ClientTransaction.class);
if (instance == null) {
instance = new ClientTransaction();
}
// 入参的 client 就是 ApplicationThread,存到成员变量 mClient 中
instance.mClient = client;
instance.mActivityToken = activityToken;
return instance;
}

public void schedule() throws RemoteException {
// 回到 ActivityThread#ApplicationThread 中
mClient.scheduleTransaction(this);
}
}

public final class ActivityThread extends ClientTransactionHandler {
private class ApplicationThread extends IApplicationThread.Stub {
@Override
public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
// 实际是调用父类 ClientTransactionHandler 中的方法
ActivityThread.this.scheduleTransaction(transaction);
}
}
}

public abstract class ClientTransactionHandler {
void scheduleTransaction(ClientTransaction transaction) {
transaction.preExecute(this);
// 发送 Message 到 ActivityThread,回到 App 进程
sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}
}

需要注意的是,ClientTransaction, ClientLifecycleManager, ActivityThread 都并不直接执行事务:

  • ClientTransaction 只用于记录事务。
  • ClientLifecycleManager 调用 scheduleTransaction(...) 只是提交事务。
  • ActivityThread 调用父类方法 ClientTransactionHandler#scheduleTransaction(...) 也只是提交事务。

真正用于执行事务的是 ActivityThread 的成员变量:TransactionExecutor mTransactionExecutor

1.3.3 执行Actviity启动事务

上文中 ClientTransactionHandler 发送了 EXECUTE_TRANSACTION 消息:

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
public final class ActivityThread extends ClientTransactionHandler {
// 入参传入了自己,TransactionExecutor 才是真正的事务「执行器」。
// An executor that performs multi-step transactions.
private final TransactionExecutor mTransactionExecutor = new TransactionExecutor(this);

class H extends Handler {
public void handleMessage(Message msg) {
case EXECUTE_TRANSACTION: {
final ClientTransaction transaction = (ClientTransaction) msg.obj;
mTransactionExecutor.execute(transaction);
}
}
}
}

public class TransactionExecutor {
// ActivityThread 在成员变量初始化时把自己传进来,所以 mTransactionHandler 就是 ActivityThread 本身。
private ClientTransactionHandler mTransactionHandler;

/** Initialize an instance with transaction handler, that will execute all requested actions. */
public TransactionExecutor(ClientTransactionHandler clientTransactionHandler) {
mTransactionHandler = clientTransactionHandler;
}

public void execute(ClientTransaction transaction) {
// 用于回调 onCreate()
executeCallbacks(transaction);
// 用于流转到 onStart(), onResume()
executeLifecycleState(transaction);
}

/** Cycle through all states requested by callbacks and execute them at proper times. */
public void executeCallbacks(ClientTransaction transaction) {
// transaction.getCallbacks() 获取的 Callback 实际是之前 ActivityStackSupervisor#realStartActivityLocked 中,
// ClientTransaction.addCallback(LaunchActivityItem) 传入的 LaunchActivityItem。
final List<ClientTransactionItem> callbacks = transaction.getCallbacks();
for (...) {
final ClientTransactionItem item = callbacks.get(i);
item.execute(mTransactionHandler, token, mPendingActions);
item.postExecute(mTransactionHandler, token, mPendingActions);
}
}

/** Transition to the final state if requested by the transaction. */
private void executeLifecycleState(ClientTransaction transaction) {
final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest();
......
lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
}
}

TransactionExecutor#execute(ClientTransaction) 分为两个步骤:

  • executedCallbacks(ClientTransaction) 用于使 Activity 进入 onCreate 状态。
  • executeLifecycleState(ClientTransaction) 用于使 Activity 生命周期流转到 onResume 状态。

1.4 Activity启动事务总结

Activity 的启动事务可以分成两大块:Application 的初始化、Activity 启动事务的初始化。

(1)Application 初始化:

  • AMS 调用 ActivityThread 的 main() 方法启动。
  • main() 方法中创建一个 ActivityThread 对象,并调用 ActivityThread#attach(...),内部获取 AMS 并与自己的内部类对象 ApplicationThread 绑定。
  • 绑定成功后,AMS 向 ActivityThread 发送 BIND_APPLICATION 消息,ActivityThread 回调 Application 的 onCreate 生命周期。
  • ActivityThread 调用 ActivityTaskManagerService#attachApplication(...),尝试启动 Activity。
  • ActivityTaskManagerService 调用 RootActivityContainer#attachApplication(...)

(2)Activity 启动事务初始化:

  • RootActivityContainer 调用 ActivityStackSupervisor#realStartActivityLocked(...)
  • ActivityStackSupervisor 创建 ClientTransaction 实例,传入 ApplicationThread,并调用 ClientTransaction#addCallback(LaunchActivityItem)ClientTransaction#setLifecycleStateRequest(ResumeActivityItem)
  • ActivityStackSupervisor 调用 ClientLifecycleManager#scheduleTransaction(...),并传入之前创建的 ClientTransaction 对象。
  • ClientLifecycleManager 调用 ClientTransaction#schedule()
  • ClientTransaction 调用 ApplicationThread#scheduleTransaction(...)
  • ActivityThread 调用父类的 ClientTransactionHandler#scheduleTransaction(...) 发送一条 EXECUTE_TRANSACTION 消息。
  • ActivityThread 收到消息后调用 TransactionExecutor#execute(ClientTransaction)
  • TransactionExecutor 分别调用 executeCallbacks(ClientTransaction)(对应 onCreate)和 executeLifecycleState(ClientTransaction)(对应 onStart 和 onResume)。

从 TransactionExecuotr 正式调用 execute(...) 执行事务开始,Activity 才正式进入生命周期流转阶段。


2. Activity生命周期流转

2.1 onCreate

按照上文中 TransactionExecutor#execute(ClientTransaction) 的调用顺序,先执行 executedCallbacks(ClientTransaction)

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 class TransactionExecutor {
public void execute(ClientTransaction transaction) {
// 用于回调 onCreate()
executeCallbacks(transaction);
// 用于流转到 onStart(), onResume()
executeLifecycleState(transaction);
}
public void executeCallbacks(ClientTransaction transaction) {
// 通过上文可以知道,callback 就是 LaunchActivityItem
final List<ClientTransactionItem> callbacks = transaction.getCallbacks();
......
for (...) {
final ClientTransactionItem item = callbacks.get(i);
// 所以实际上调用的是 LaunchActivityItem#execute
item.execute(mTransactionHandler, token, mPendingActions);
item.postExecute(mTransactionHandler, token, mPendingActions);
}
}
}

public class LaunchActivityItem extends ClientTransactionItem {
@Override
public void execute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
// 传入的 client 就是 ActivityThread
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
ActivityClientRecord r = new ActivityClientRecord(...);
// 重点就是这一步调用的 ActivityThread#handleLaunchActivity
client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
}

此后才与 API 29 以下版本的逻辑重合。

2.1.1 handleLaunchActivity()

LaunchActivityItem#execute(...) 创建了一个 ActivityClientRecord 对象用于持有目标 Activity 以及一些相关资源,再通过 ActivityThread.handleLaunchActivity(...) 创建并启动目标 Activity:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public final class ActivityThread extends ClientTransactionHandler {
/**
* Extended implementation of activity launch. Used when server requests a launch or relaunch.
*/
@Override
public Activity handleLaunchActivity(ActivityClientRecord r,
PendingTransactionActions pendingActions, Intent customIntent) {
......
// 关键步骤 performLaunchActivity
final Activity a = performLaunchActivity(r, customIntent);
if (a != null) {
......
} else {
// If there was an error, for any reason, tell the activity manager to stop us.
try {
ActivityTaskManager.getService().finishActivity(...);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
}
}

handleLaunchActivity(...) 主要是调用 performLaunchActivity(...) 生成一个 Activity 实例对象,并在生成失败时直接通知 ActivityTaskManagerService 结束该 Activity,或是抛出一个异常,中断后续流程。

2.1.2 performLaunchActivity()

performLaunchActivity(...) 是实际创建 Activity 的方法,过程中调用了一个重要方法 Activity#attach

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public final class ActivityThread extends ClientTransactionHandler {
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
Window window = null;
if (r.mPendingRemoveWindow != null && r.mPreserveWindow) {
// 从 ActivityClientRecord 中取出了一个 Window
window = r.mPendingRemoveWindow;
r.mPendingRemoveWindow = null;
r.mPendingRemoveWindowManager = null;
}
// 这个方法是重点,并且注意参数中传入了上面从 ActivityClientRecord 中取出的 Window
activity.attach(...);
// 通知 Instrumentation 回调 Activity 的 onCreate()
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
}
}

在冷启 Activity 时,ActivityClientRecord 是在 LaunchActivityItem#execute(...) 中被 new 出来的,所以 r.mPendingRemoveWindow 肯定是 null,那什么时候才能进入 if 的条件呢?换句话说,什么时候 ActivityThread#performLaunchActivity(...) 传入的 ActivityClientRecord 中 mPendingRemoveWindow != null 呢?查找一下 ActivityClientRecord 中 mPendingRemoveWindow 写入的地方,发现在 handleDestroyActivity(...) 中有这么一段:

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
public final class ActivityThread extends ClientTransactionHandler {
@Override
public void handleDestroyActivity(IBinder token, boolean finishing, int configChanges,
boolean getNonConfigInstance, String reason) {
ActivityClientRecord r = performDestroyActivity(...);
if (r != null) {
View v = r.activity.mDecor;
if (v != null) {
......
if (r.activity.mWindowAdded) {
if (r.mPreserveWindow) {
// 核心逻辑:
// Hold off on removing this until the new activity's
// window is being added.
r.mPendingRemoveWindow = r.window;
r.mPendingRemoveWindowManager = wm;
// We can only keep the part of the view hierarchy that we control,
// everything else must be removed, because it might not be able to
// behave properly when activity is relaunching.
r.window.clearContentView();
} else {
wm.removeViewImmediate(v);
}
}
}
}
}
}

看源码注释就能明白,当一个 Activity 销毁时,会在其 ActivityVlientRecord 中把自己的 Window 保存到 mPendingRemoveWindow 中,然后移除 Window 中所有 View,直到新的 Activity 的 Window 被添加为止:

  • handleRelaunchActivityInner(...) 中,先调用了 handleDestroyActivity(...),这一步就把当前 Activity 的 Window 存进了 mPendingRemoveWindow
  • 接下来调用了 handleLaunchActivity(...)
  • 然后在其内部调用了 performLaunchActivity(...)

这下明白了,当一个 Activity 被系统回收等等场景销毁时,有可能接下来又会回到这个 Activity,这种情况下就可以先把 Window 缓存下来,当自己这个 Activity 再次被激活时,就可以直接复用 Activity 上一次的 Window 而不需要从新分配。当然,由于 r.window.clearContentView();,Window 中的 View 被清空了,所以还是需要重新走一遍视图加载。这样做的好处也许是在效率和内存消耗中的一种折中,或许是因为 View 会占用很大内存,所以需要回收 View,但 Window 本身占用较少,每次都回收再让系统重新分配可能比缓存占用的内存更多、或者可能带来更大的内存抖动风险,所以选择临时缓存。继续查看 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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
public class Activity {
// 通过上文可知,冷启 Activity 时传入的 window 是 null,如果是 performRelaunchActivity 则会传入 Activity 上一次销毁前缓存下来的 window。
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) {
// 创建一个 Window 实例,这里 mWindow 是 Window 类型的接口对象,该接口只有 PhoneWindow 唯一一个实例对象,
// 并且当新启动一个 Activity 时,这里传入的 window 也是 null。
mWindow = new PhoneWindow(this, window, activityConfigCallback);
mUiThread = Thread.currentThread();
// 调用系统服务创建一个 WindowManager 的实例 WindowManagerImpl,并存进 mWindow (PhoneWindow) 中,
// 此外还存入了 IBinder 类型的 token,可以理解为用于在后续 App 创建 Window 时的授权。
mWindow.setWindowManager(
(WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
mToken, mComponent.flattenToString(),
(info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
if (mParent != null) {
mWindow.setContainer(mParent.getWindow());
}
// 同时也把上面创建的 WindowManager 存入 Activity 内。
mWindowManager = mWindow.getWindowManager();
}
}

public class PhoneWindow extends Window implements MenuBuilder.Callback {
/**
* Constructor for main window of an activity.
*/
public PhoneWindow(Context context, Window preservedWindow,
ActivityConfigCallback activityConfigCallback) {
// 注意这里的判断条件,是需要 preservedWindow != null 才去初始化 DecorView。
// 如果是新启动一个 Activity,传进来的 preservedWindow == null,是不会走这个逻辑的。
if (preservedWindow != null) {
mDecor = (DecorView) preservedWindow.getDecorView();
mElevation = preservedWindow.getElevation();
mLoadElevation = false;
mForceDecorInstall = true;
// If we're preserving window, carry over the app token from the preserved
// window, as we'll be skipping the addView in handleResumeActivity(), and
// the token will not be updated as for a new window.
getAttributes().token = preservedWindow.getAttributes().token;
}
......
}

至此 Activity.attach() 执行完毕,接下来会由 Instrumentation 回调 Activity.onCreate(),表示 Activity 走到了 onCreate() 的生命周期。

2.1.3 onCreate总结

Activity 在 onCreate 时的流程可以这么总结:

  • Application 成功启动、初始化、并绑定 AMS 后,调用 TransactionExecutor#execute(),内部先执行 executeCallbacks(ClientTransaction),调用 LaunchActivityItem#execute(...),进而调用 handleLaunchActivity(...),进入启动 Activity 的流程。
  • handleLaunchActivity(...) 内部调用 performLaunchActivity(...)
  • performLaunchActivity(...) 判断传入的 ActivityClientRecord.mPendingRemoveWindow 是否为空。
    • 如果是通过 LaunchActivityItem#execute(...) 触发的 performLaunchActivity(...),则 ActivityClientRecord.mPendingRemoveWindow == null
    • 否则如果一个 Activity 是已经启动后被 handleRelaunchActivityInner(...) 唤醒的,就会先调用 handleDestroyActivity(...),这一步将当前 Activity 的 Window 缓存在 mPendingRemoveWindow 后再销毁,然后调用 performLaunchActivity(...),这样重新启动的同一个 Activity 就能拿到上一次销毁时保存的 Window 了。
  • performLaunchActivity(...) 中从 ActivityClientRecord 取出对应的 Activity,并调用 Activity.attach(...),传入了从 ActivityClientRecord 中取出的 mPendingRemoveWindow(可能为空)。
  • Activity.attach(...) 中直接 new 了一个新的 PhoneWindow,构造方法中传入了 ActivityClientRecord.mPendingRemoveWindow,PhoneWindow 判断 mPendingRemoveWindow 是否为空,为空说明是新启动的 Activity,否则说明是 relaunch 的 Activity。
  • 如果传入的 mPendingRemoveWindow 不为空,则从 mPendingRemoveWindow 中取出 DecorView,并作为当前 Activity 自己的 DecorView,否则不处理。
  • 创建完新的 PhoneWindow 后,再通过系统服务创建一个 WindowManager。
  • 将这个新建的 WindowManager 绑定到 Activity 新建的 PhoneWindow 中,以及在 Activity 本身中保存。
  • 此时 Activity 和对应的 ActivityClientRecord 共用同一个 WindowManager,但注意,Activity 在 attach(...)new 出来的 Window,暂时还没有存入到对应的 ActivityClientRecord 中。
  • 如果

也就是说,走完 onCreate() 的流程后,一个 Activity 就创建好了自己的 Window 并绑定了 WindowManager。并且如果这个 Activity 是 relaunch 的,还会直接复用上一次销毁时缓存的 Window 和 DecorView;但如果是新启动的 Activity,则到当前为止,Activity 已经创建好了 Window,但还不具有 DecorView。

2.2 onStart

按照上文中 TransactionExecutor#execute(ClientTransaction) 的调用顺序,第二步调用 executeLifecycleState(ClientTransaction)

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
public class TransactionExecutor {

private TransactionExecutorHelper mHelper = new TransactionExecutorHelper();

public void execute(ClientTransaction transaction) {
// 用于回调 onCreate()
executeCallbacks(transaction);
// 用于流转到 onStart(), onResume()
executeLifecycleState(transaction);
}
/** Transition to the final state if requested by the transaction. */
private void executeLifecycleState(ClientTransaction transaction) {
final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest();
// 在生成 ClientTransaction 的方法 ActivityStackSupervisor#realStartActivityLocked 中,
// andResume == true 时 lifecycleItem 时 ResumeActivityItem 类型,
// 实际上 transaction 持有的 lifecycleItem 是 `ResumeActivityItem` 类型,
// 因此 lifecycleItem.getTargetState() 返回的就是 ON_RESUME。
cycleToPath(r, lifecycleItem.getTargetState(), true /* excludeLastState */, transaction);
// 这里传入的 mTransactionHandler 就是 ActivityThread
lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
}
/**
* Transition the client between states with an option not to perform the last hop in the
* sequence. This is used when resolving lifecycle state request, when the last transition must
* be performed with some specific parameters.
*/
private void cycleToPath(ActivityClientRecord r, int finish, boolean excludeLastState,
ClientTransaction transaction) {
// 由于此前 Activity 刚完成 onCreate,所以 start == ON_CREATE,
// executeLifecycleState(...) 方法中传入的 finish == ON_RESUME,
// executeLifecycleState(...) 方法中传入的 excludeLastState == true。
final int start = r.getLifecycleState();
final IntArray path = mHelper.getLifecyclePath(start, finish, excludeLastState);
performLifecycleSequence(r, path, transaction);
}
/** Transition the client through previously initialized state sequence. */
private void performLifecycleSequence(ActivityClientRecord r, IntArray path,
ClientTransaction transaction) {
final int size = path.size();
for (int i = 0, state; i < size; i++) {
state = path.get(i);
switch (state) {
case ON_START: {
mTransactionHandler.handleStartActivity(r, mPendingActions);
break;
}
}
}
}
}

public class TransactionExecutorHelper {
/**
* Calculate the path through main lifecycle states for an activity and fill
* @link #mLifecycleSequence} with values starting with the state that follows the initial
* state.
* <p>NOTE: The returned value is used internally in this class and is not a copy. It's contents
* may change after calling other methods of this class.</p>
*/
@VisibleForTesting
public IntArray getLifecyclePath(int start, int finish, boolean excludeLastState) {
if (finish >= start) {
for (int i = start + 1; i <= finish; i++) {
mLifecycleSequence.add(i);
}
}
// Remove last transition in case we want to perform it with some specific params.
if (excludeLastState && mLifecycleSequence.size() != 0) {
mLifecycleSequence.remove(mLifecycleSequence.size() - 1);
}
return mLifecycleSequence;
}
}

由于 for(...) 循环中的起始序号是从 start + 1 开始,实际上就是先把 ON_CREATE(不包括)到 ON_RESUME(包括)之间的生命周期都添加到了 mLifecycleSequence,但由于 excludeLastState == true,因此 mLifecycleSequence 又移除了最后一项(也即 ON_RESUME),因此最终 path = mHelper.getLifecyclePath(start, finish, excludeLastState) 返回的 mLifecycleSequence 只包含 ON_START

由于 mTransactionHandler 就是 ActivityThread,所以 TransactionExecutor#performLifecycleSequence(...) 最终会调用 ActivityThread#handleStartActivity(...)

2.2.1 handleStartActivity()

ActivityThread#handleStartActivity(...) 主要是调用 performStart(String),并判断是否需要回调 onRestoreInstanceState()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public final class ActivityThread extends ClientTransactionHandler {
@Override
public void handleStartActivity(ActivityClientRecord r,
PendingTransactionActions pendingActions) {
final Activity activity = r.activity;
// Start
activity.performStart("handleStartActivity");
r.setState(ON_START);
// Restore instance state
if (pendingActions.shouldRestoreInstanceState()) {
if (r.isPersistable()) {
if (r.state != null || r.persistentState != null) {
mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state,
r.persistentState);
}
} else if (r.state != null) {
mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
}
}
if (pendingActions.shouldCallOnPostCreate()) {
}
}
}

2.2.2 performStart()

需要注意的是,performStart(...) 是 Activity 内的方法,而不是 ActivityThread 的方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class Activity {
final void performStart(String reason) {
mInstrumentation.callActivityOnStart(this);
}
}

public class Instrumentation {
/**
* Perform calling of an activity's {@link Activity#onStart}
* method. The default implementation simply calls through to that method.
*
* @param activity The activity being started.
*/
public void callActivityOnStart(Activity activity) {
activity.onStart();
}
}

performStart() 主要就是通知 Instrumentation 来回调 Activity 的 onStart 生命周期。

2.2.3 onStart总结

Activity 在 onStart 的流程可以这么总结:

  • 如果 ActivityThreade 在 handleLauncherActivity 期间,通过 performLauncherActivity() 未能成功创建一个 Activity 实例对象,则会请求 AMS 直接中断后续流程。
  • 否则 executeCallbacks(ClientTransaction) 执行完 handleLaunchActivity 后,再执行 executeLifecycleState(ClientTransaction)
  • executeLifecycleState 内先执行 cycleToPath(...),回调 Activity 需要经过的生命周期。
  • cycleToPath 传入 ON_CREATE, ON_START, ONRESUME,但从第二个开始选择,并排除最后一个,因此最终只有 ON_START 被送入 TransactionExecutor#performLifecycleSequence(...),并由此回调 ActivityThread#handleActivityStart(...)
  • ActivityThread 调用 Activity#performStart(...),Activity 调用 Instrumentation#callActivityOnStart(this);,并由 Instrumentation 回调 Activity 的 onStart 生命周期。
  • ActivityThread 判断是否需要回调 onRestoreInstanceState 以及 onPostCreate。

2.3 onResume

回顾 TransactionExecutor#executeLifecycleState,当 cycleToPath(...) 执行完毕后,Activity 需要先经过的生命周期均已回调:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class TransactionExecutor {
/** Transition to the final state if requested by the transaction. */
private void executeLifecycleState(ClientTransaction transaction) {
final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest();
// 在生成 ClientTransaction 的方法 ActivityStackSupervisor#realStartActivityLocked 中,
// andResume == true 时 lifecycleItem 时 ResumeActivityItem 类型,
// 实际上 transaction 持有的 lifecycleItem 是 `ResumeActivityItem` 类型,
// 因此 lifecycleItem.getTargetState() 返回的就是 ON_RESUME。
cycleToPath(r, lifecycleItem.getTargetState(), true /* excludeLastState */, transaction);
// 这里传入的 mTransactionHandler 就是 ActivityThread
lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
}
}

上文也提到此处的 lifecycleItem 实际就是 ResumeActivityItem,因此查看 ResumeActivityItem#execute(...) 方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
/**
* Request to move an activity to resumed state.
* @hide
*/
public class ResumeActivityItem extends ActivityLifecycleItem {
@Override
public void execute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
// client 就是 ActivityThread,从 AMS 回到 ActivityThread#handleResumeActivity 中。
client.handleResumeActivity(token, true /* finalStateRequest */, mIsForward,
"RESUME_ACTIVITY");
}
}

2.3.1 handleResumeActivity()

ActivityThread#handleResumeActivity 内部通过调用 performResumeActivity(...) 获取包装了各类资源的 ActivityClientRecord,并用该 ActivityClientRecord 为 Activity 初始化与视图相关的资源,例如绑定 Window,初始化 DecorView 等:

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
public final class ActivityThread extends ClientTransactionHandler {
public void handleResumeActivity(IBinder token, boolean finalStateRequest, boolean isForward, String reason) {
// 通过 token 从所有 ActivityClientRecord 中取出目标
// 如果是新启动的 Activity,可以理解为这里取出来的 ActivityClientRecord 就是上面 startActivityNow(...) 中 new 出来的 ActivityClientRecord
final ActivityClientRecord r = performResumeActivity(token, finalStateRequest, reason);
final Activity a = r.activity;
if (r.window == null && !a.mFinished && willBeVisible) {
// ActivityThread#performLaunchActivity 阶段在 Activity#attach 中 new 了一个 PhoneWindow,但 ActivityClientRecord 并没有持有 PhoneWindow,
// 这一步就将 PhoneWindow 存入了 ActivityClientRecord,此时 Activity 和对应的 ActivityClientRecord 都持有了同一个 Window 和 WindowManager 对象
r.window = r.activity.getWindow();
// 获取目标 Activity 的 Window 的 DecorView
// Window#getDecorView() 内部包含两个逻辑,如果持有的 DecorView 已存在(例如 relaunch 的场景)则直接返回,否则(例如 startActivityNow 的场景)就 new 一个再返回
// 详见下面的源码
View decor = r.window.getDecorView();
decor.setVisibility(View.INVISIBLE);
// 取出之前 Activity.attach() 中存入 PhoneWindow 的 WindowManager 接口实例 WindowManagerImpl 对象。
ViewManager wm = a.getWindowManager();
// 创建的 DecorView 的窗口属性
WindowManager.LayoutParams l = r.window.getAttributes();
// 将创建的的 DecorView 作为目标 Activity 的 DecorView,此时还未创建 ViewRootImpl
a.mDecor = decor;
// 判断 Activity 的 Window 是不是从上一次销毁时缓存下来的,如果是则通知 DecorView 的所有子 View 即将重建
if (r.mPreserveWindow) {
// 获取 DecorView 的 ViewRootImpl,如果没有则返回 null
// Normally the ViewRoot sets up callbacks with the Activity
// in addView->ViewRootImpl#setView. If we are instead reusing
// the decor view we have to notify the view root that the
// callbacks may have changed.
ViewRootImpl impl = decor.getViewRootImpl();
// 当 Activity 是 relaunch 的时候,Window 和其持有的 DecorView 是从上一次缓存下来的,则 DecorView#getViewRootImpl 才不为空
if (impl != null) {
// 通知所有的子 View:「准备重新创建视图」
impl.notifyChildRebuilt();
}
}
if (a.mVisibleFromClient) {
if (!a.mWindowAdded) {
a.mWindowAdded = true;
// 调用 WindowManagerImpl#addView
wm.addView(decor, l);
}
}
}
// 清除掉 Activity 缓存的 Window 等,并重置了 r.mPreserveWindow 标志位
// Get rid of anything left hanging around.
cleanUpPendingRemoveWindows(r, false /* force */);
}
}

这一段逻辑可以分为两个关键点:

  • r.window.getDecorView();: 如果 Activity 不是 ReLaunch 的,也没有调用过 setContentView(...),则需要先初始化 DecorView。
  • wm.addView(decor, l);: 通过 WindowManagerImpl#addView 传入 DecorView,然后创建 ViewRootImpl,并使得 ViewRootImpl 持有 DecorView。

(1)初始化 DecorView:

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
// 对应上面 View decor = r.window.getDecorView(); 的源码
public class PhoneWindow extends Window {

ViewGroup mContentParent;

/**
* Retrieve the top-level window decor view (containing the standard
* window frame/decorations and the client's content inside of that), which
* can be added as a window to the window manager.
*
* <p><em>Note that calling this function for the first time "locks in"
* various window characteristics as described in
* {@link #setContentView(View, android.view.ViewGroup.LayoutParams)}.</em></p>
*
* @return Returns the top-level window decor view.
*/
public final @NonNull View getDecorView() {
if (mDecor == null || mForceDecorInstall) {
// 内部逻辑其实就是 new 出来一个 DecorView,并与当前 Window 绑定
installDecor();
}
return mDecor;
}

private void installDecor() {
if (mContentParent == null) {
// mContentParent 其实就是 DecorView 加载出来之后的布局容器 ViewGroup
mContentParent = generateLayout(mDecor);
}
}

(2)通过 WindowManagerImpl#addView 创建 ViewRootImpl 并持有 DecorView:

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
public final class WindowManagerImpl implements WindowManager {

private final WindowManagerGlobal mGlobal = WindowManagerGlobal.getInstance();

// handleResumeActivity(...) 中,调用该方法传入的 View 实际上就是 DecorView
public void addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {
applyDefaultToken(params);
// 这个 mGlobal 是 WindowManagerGlobal 实例对象
mGlobal.addView(view, params, mContext.getDisplay(), mParentWindow);
}
}

// 对应 mGlobal.addView(...) 的源码
public final class WindowManagerGlobal {
// 这里传入的 View 实际上是 DecorView
public void addView(View view, ViewGroup.LayoutParams params, Display display, Window parentWindow) {
ViewRootImpl root;
synchronized (mLock) {
// 创建 ViewRootImpl。
root = new ViewRootImpl(view.getContext(), display);
// mRoots 是一个 ArrayList<ViewRootImpl> 类型的集合。
mRoots.add(root);
mParams.add(wparams);
// do this last because it fires off messages to start doing things
try {
// ViewRootImpl 持有 DecorView。
root.setView(view, wparams, panelParentView);
}
}
}
}

终于找到了 ViewRootImpl 初始化的地方,其构造方法内绑定了初始化时的线程:

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
public final class ViewRootImpl implements ViewParent {

final IWindowSession mWindowSession;

public ViewRootImpl(Context context, Display display) {
// 创建一个 WindowSession,App 创建 Window 时,实际上都是通过 ViewRootImpl 拿到 WindowSession,
// 再通过 WindowSession 与 WindowManagerService 交互完成的,
// 其中用到了 Activity#attach 传入 PhoneWindow 的 IBinder token。
// 所以实际上 PhoneWindow 持有了和 Window 相关的信息,但真正和 WMS 通信的是 ViewRootImpl。
mWindowSession = WindowManagerGlobal.getWindowSession();
// 绑定了初始化时的线程
mThread = Thread.currentThread();
}
public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {
// 传入的 view 就是 DecorView。
synchronized (this) {
if (mView == null) {
mView = view;
......
// 调用 WindowSession#addToDisplay(...),才是真正创建了一个 Window。
res = mWindowSession.addToDisplay(...);
}
}
}
}

然后 Instrumentation 会回调 Activity.onResume(),表示 Activity 进入到了 onResume() 的生命周期。到了这一步,Activity 初始化了 PhoneWindow 以及 DecorView,并且在 ViewRootImpl 中加载了 DecorView,这也表示 Activity 已经从视觉上可见。

2.3.2 performResumeActivity()

ActivityThread 在 Activity 的 onResume 阶段大部分逻辑都在 handlerResumeActivity(...) 内,和视图资源相关。performResumeActivity(...) 则主要是为 handlerResumeActivity(...) 提供了依赖的 ActivityClientRecord 资源,以及通知 Instrumentation 回调 onResume()

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
public final class ActivityThread extends ClientTransactionHandler {
final ArrayMap<IBinder, ActivityClientRecord> mActivities = new ArrayMap<>();
public ActivityClientRecord performResumeActivity(IBinder token, boolean finalStateRequest,
String reason) {
final ActivityClientRecord r = mActivities.get(token);
try {
r.activity.performResume(r.startsNotResumed, reason);
r.state = null;
r.persistentState = null;
r.setState(ON_RESUME);
}
return r;
}
}

public class Activity {
final void performResume(boolean followedByPause, String reason) {
dispatchActivityPreResumed();
performRestart(true /* start */, reason);
// mResumed is set by the instrumentation
mInstrumentation.callActivityOnResume(this);
}
}

public class Instrumentation {
public void callActivityOnResume(Activity activity) {
activity.mResumed = true;
activity.onResume();
}
}

2.3.3 onResume总结

Activity 在 onResume 时的流程可以这么总结:

  • ActivityThread 已经通过 handleLaunchActivity(...) 成功创建 Activity 实例,并且通过 TransactionExecutor#cycleToPath(...) 回调了 Activity 需要经历的生命周期。
  • TransactionExecutor 调用 ResumeActivityItem#execute(...),从而调用了 ActivityThread#handleResumeActivity(...)
  • ActivityThread 在 handleResumeActivity 中通过 performResumeActivity(...) 获取对应的 ActivityClientRecord。
  • 获取 DecorView,分为两种逻辑:由于 startActivityNow 触发的 handleResumeActivity、以及由于 relaunch 触发的 handleResumeActivity。
    • 如果是由于 startActivityNow 触发的,则 DecorView 尚未创建,立即创建一个 DecorView,此时 DecorView 或者说 Activity 尚未初始化 ViewRootImpl。
    • 如果是由于 relaunch 触发的,则 Window、DecorView 均是从上一次销毁时缓存中复用的,此时 DecorView 已经初始化过了 ViewRootImpl,也即 Activity 已经拥有 ViewRootImpl 了,只需要通知所有子 View 即将重建。
  • 如果 Activity 还未初始化 ViewRootImpl(对应 startActivityNow 的场景),则调用 WindowManager#addView(...),其内部初始化了 ViewRootImpl,将初始化 ViewRootImpl 时的所在线程,作为 ViewRootImpl 的初始线程。
  • ViewRootImpl 持有 DecorView。

也就是说,到了 onResume 这一步,Activity 已经创建了 DecorView 和 ViewRootImpl,并且对 ViewRootImpl 的原始线程做了初始化。此时 Activity 已经完整具有了 Window、DecorView、ViewRootImpl。


3. Activity布局加载流程

3.1 setContentView()

接下来就是 Activity 的另一项重要功能,加载布局文件。通常加载布局文件都是通过 setContentView(...) 实现的,这里其实分为两个版本:

(1)早期的 Activity 直接继承自 Activity 类:

1
2
3
4
5
6
public class Activity {
public void setContentView(@LayoutRes int layoutResID) {
getWindow().setContentView(layoutResID);
initWindowDecorActionBar();
}
}

也就是通过之前 Activity.attach(...) 时创建的 PhoneWindow 去直接加载布局。

(2)新版本的 Activity 继承自 AppCompatActivity 类:

1
2
3
4
5
6
7
8
9
10
11
12
13
public class AppCompatActivity {
public void setContentView(@LayoutRes int layoutResID) {
// getDelegate() 返回一个 AppCompatDelegate 接口类型的实例对象
getDelegate().setContentView(layoutResID);
}
public AppCompatDelegate getDelegate() {
if (mDelegate == null) {
// 实际上内部就是 new 了一个 AppCompatDelegateImpl
mDelegate = AppCompatDelegate.create(this, this);
}
return mDelegate;
}
}

再看看 AppCompatDelegateImpl.setContentView()

1
2
3
4
5
6
7
8
9
10
class AppCompatDelegateImpl extends AppCompatDelegate {
public void setContentView(int resId) {
// 注意这个方法,创建了一个叫 subDecor 的东西
ensureSubDecor();
ViewGroup contentParent = mSubDecor.findViewById(android.R.id.content);
contentParent.removeAllViews();
LayoutInflater.from(mContext).inflate(resId, contentParent);
mAppCompatWindowCallback.getWrapped().onContentChanged();
}
}

主要分为两个部分:

  • ensureSubDecor();: 创建一个 SubDecorView。
  • 从 SubDecorView 中找到 ID 为 android.R.id.contentViewGroup contentParent,清除其中所有 View,并把传入的布局 ID resId 解析并加载进 contentParent 内。

(1)创建 SubDecorView:

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
class AppCompatDelegateImpl extends AppCompatDelegate {
private void ensureSubDecor() {
if (!mSubDecorInstalled) {
// 真正的创建是这个方法
mSubDecor = createSubDecor();

// 可以看到在 setContentView(...) 内部加载了标题和 ActionBar
// 这也是为什么在 Activity 中,对 ActionBar 或 Title 的修改必须放在 setContentView(...) 调用之前
// If a title was set before we installed the decor, propagate it now
CharSequence title = getTitle();
if (!TextUtils.isEmpty(title)) {
if (mDecorContentParent != null) {
mDecorContentParent.setWindowTitle(title);
} else if (peekSupportActionBar() != null) {
peekSupportActionBar().setWindowTitle(title);
} else if (mTitleView != null) {
mTitleView.setText(title);
}
}
mSubDecorInstalled = true;
}
}
private ViewGroup createSubDecor() {
TypedArray a = mContext.obtainStyledAttributes(R.styleable.AppCompatTheme);
// 这下面有一堆 if - else 都只是为了确定这个 Activity 对应 Window 的样式
if (...) {......}
a.recycle();

// 先确保了 Window 已经初始化
// Now let's make sure that the Window has installed its decor by retrieving it
ensureWindow();
// 从 Activity 存储的 PhoneWindow 中获取 DecorView,但并不是需要拿到 DecorView 实例,
// 而是为了像上面 handleResumeActivity(...) 中的 r.activity.getWindow() 一样,确保 DecorView 已被创建
mWindow.getDecorView();
// 这个就是目标 subDecor
ViewGroup subDecor = null;

if (!mWindowNoTitle) {
// 如果 Activity 含有 WindowTitle:
if (mIsFloating) {
// 加载悬浮窗样式的 subDecor
subDecor = (ViewGroup) inflater.inflate(...);
} else if (mHasActionBar) {
// 加载有 ActionBar 样式的 subDecor
subDecor = (ViewGroup) LayoutInflater.from(themedContext).inflate(...);
// 这个 mDecorContentParent 是 ActionBarOverlayLayout 类型的,用于管理 ActionBar
mDecorContentParent = (DecorContentParent) subDecor.findViewById(R.id.decor_content_parent);
mDecorContentParent.setWindowCallback(getWindowCallback());
}
}
if (subDecor == null) {
// 如果仍然无法加载出 subDecor,就抛出异常
throw new IllegalArgumentException("AppCompat does not support the current theme features: { " + ...... + " }");
}
// 将 subDecor 加载到 PhoneWindow 中
mWindow.setContentView(subDecor);
return subDecor;
}
}

(2)将传入的布局 ID 解析成 View 并加载进 SubDecor 的一个 ViewGroup 子元素 contentParent 中:

createSubDecor() 中,先确保 Window 和 DecorView 已创建,然后根据 Title 和 ActionBar 的样式不同,通过 inflate 的方式加载对应的模板 subDecor。然后再从加载好的 SubDecor 中通过 findViewById(...) 的方式获取到一个 ViewGroup 子元素 contentParent 并把布局加载进其中,也就是说,实际上在 Activity 中调用的 setContentView(int resId) 传入的布局文件,是加载在 subDecor 的一个子 View 中,而 DecorView 又持有了 SubDecor。

如果 Activity 含有 WindowTitle,且具有 ActionBar,还会从 subDecor 的模板布局中通过 findViewById(int) 的方式获取一个叫 mDecorContentParent 的 ActionBarOverlayLayout 类型的 View,从类名也能看出这个 View 就是专门负责 ActionBar 的。

当 subDecor 被成功创建后,通过 mWindow.setContentView(subDecor); 把 subDecor 添加到 PhoneWindow 中:

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
public class PhoneWindow extends Window {
// 传入的参数 View 就是 subDecor
public void setContentView(View view) {
// 这里也可以看出,默认情况下是全屏的
setContentView(view, new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));
}
// 传入的参数 View 就是 subDecor
public void setContentView(View view, ViewGroup.LayoutParams params) {
// mContentParent 是 DecorView 中的一个 ViewGroup 子元素。
if (mContentParent == null) {
installDecor();
} else if (!hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
mContentParent.removeAllViews();
}

if (hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
......
} else {
// 传入的参数 View 就是 subDecor,所以实际是将 SubDecor 添加到 DecorView 的 ViewGroup 子元素 mContentParent 内。
mContentParent.addView(view, params);
}
mContentParent.requestApplyInsets();
final Callback cb = getCallback();
if (cb != null && !isDestroyed()) {
cb.onContentChanged();
}
mContentParentExplicitlySet = true;
}

private void installDecor() {
if (mContentParent == null) {
// mContentParent 其实就是 DecorView 加载出来之后的布局容器 ViewGroup
mContentParent = generateLayout(mDecor);
}
}
}

需要注意的是,在 PhoneWindow 中有一个成员变量 mContentParent 是 DecorView 的一个 ViewGroup 子元素,而 AppCompatDelegateImpl#setContentView(...) 中从 SubDecor 中 findViewById(android.R.id.content) 获取了一个局部变量 contentParent 是 SubDecor 的一个 ViewGroup 子元素,二者是不同的。总的来说:

  • DecorView 分为两大部分,一个是 Title,一个是 Content;
  • PhoneWindow 根据属性从预定义的模板中加载了一个 DecorView,主要就是 Title 的样式,因为 Content 只是一个空的 ViewGroup;
  • AppCompatActivity#setContentView(...) 将布局实际上加载到了 SubDecor 的 (ViewGroup) contentParent 中;
  • 因为 DecorView 的 Content 用于包裹实际的内容,但 DecorView 没办法预知 Activity 加载的 ContentView,所以就用 SubDecor 来包裹实际的 Activity 布局;
  • 最后再把 SubDecor 加载到 DecorView 的 (ViewGroup) mContentParent 中。

并且,当调用了 setContentView(...) 后,就已经创建好了 DecorView 和 SubDecor、加载好了布局、将 DecorView 传入了 PhoneWindow,因此:

  • 如果在 onCreate 阶段调用 setContentView(...),则 ActivityThread#handleResumeActivity 阶段 r.window.getDecorView() 获取的 DecorView 就不为 null,并且 DecorView 已经加载了对应布局。
  • 否则 DecorView 和 SubDecor 都会在 ActivityThread#handleResumeActivity 阶段用默认模板加载出来。
  • 不论是否调了 setContentView(...),ViewRootImpl 都是在 ActivityThread#handleResumeActivity 阶段通过 WindowManagerImpl#addView 才加载的,并且持有了 DecorView。
  • 如果 ViewRootImpl 已经初始化并持有了默认模板的 DecorView 之后才调用 setContentView(...),由于布局最终只是加载进了 SubDecor 的一个子 ViewGroup,所以并不会重新初始化 SubDecor、DecorView、PhoneWindow、ViewRootImpl。

3.2 setContentView()总结

至此,可以对 Activty 中调用 setContentView(int resId) 后的流程做一个总结:

  • 如果是老版本直接继承自 Activity,则调用 setContentView(int resId) 后会直接把布局 inflate 到 Activity 对应的 Window 中。
  • 如果是新版本继承自 AppCompatActivity,则先确保 subDecor 已创建。
  • 在创建 subDecor 前,先确保 Window 和 DecorView 已创建。
  • 首先判断 PhoneWindow 是否创建,如果未创建则先创建 Window。
  • 然后通过 PhoneWindow#getDecorView() - installDecor() 确保了 DecorView 已被创建并根据属性初始化了一份模板布局。
  • 创建 subDecor 时,根据 Activity 及其 Window 的属性加载预置的 subDecor 模板,如果 Activity 含有 WindowTitle,且具有 ActionBar,还会从 subDecor 的模板布局中通过 findViewById(int) 的方式获取一个叫 mDecorContentParent 的 ActionBarOverlayLayout 类型的 View,专门用于管理 ActionBar 相关的视图。
  • 根据模板创建了 subDecor 后,通过 Window#setContentView(View) 将 subDecor 传入,并把传入的 subDecor 作为子 View 添加到 PhoneWindow#mContentParent 中,本质上就是把 subDecor 添加到 DecorView 中。
  • subDecor 创建好后,从 subDecor 中通过 findViewById(android.R.id.content) 获取一个布局 contentParent,接着先 remove 掉所有子 View 再 inflate 传入的布局文件。这一步才真正加载 Activity 布局。

也就是说,在 setContentView 的时候,Activity 实际上是在确保 Window 和 DecorView 均已创建的基础上,把 subDecor 根据模板创建出来并 add 进 mContentParent 这个 ViewGroup 中(mContentParent 是从 DecorView 加载出来的),然后从 subDecor 的模板布局中获取一个子元素 contentParent,最后把实际的 Activity 布局 inflatecontentParent

此外,Window 有「子 Window」的概念,例如当 Activity 创建一个 Dialog 的 Window 时,会传入把 Activity 的 PhoneWindow 作为 WindowParant,当判断 parent != null 时,就会用 parent 的 Token 创建 Window。