本文将根据Api 30(Android 11)的源码来分析Activity的启动流程。
我个人把Activity的启动流程依次分为三个阶段:
App进程中 ——[通过Binder]——> 系统进程中 ——[通过Binder]——> 回到App进程中
下面按顺序进行梳理,主要整理大体脉络,不会大量贴出源码,只展示关键代码。
一、App进程中
第一阶段在用户进程中进行,比较简单。
1. Activity
一般通过Activity.startActivity(Intent)来启动Activity。通过一系列的处理和传递,最终会走到startActivityForResult(Intent, Int, Bundle)
方法。在这里,会调用Instrumentation.execStartActivity(Context, IBinder, IBinder, Activity, Intent, int, Bundle)
方法。
2. Instrumentation
在Instrumentation的execStartActivity
方法中,有这么一句:
// Instrumentation类
int result = ActivityTaskManager.getService().startActivity(...args);
在这里,通过ActivityTaskManager.getService()
获取到一个IActivityTaskManager
对象。通过其获取方式:
// ActivityTaskManager类
public static IActivityTaskManager getService() {
return IActivityTaskManagerSingleton.get();
}
private static final Singleton<IActivityTaskManager> IActivityTaskManagerSingleton =
new Singleton<IActivityTaskManager>() {
@Override
protected IActivityTaskManager create() {
final IBinder b = ServiceManager.getService(Context.ACTIVITY_TASK_SERVICE);
return IActivityTaskManager.Stub.asInterface(b);
}
};
可以看到,这是一个Binder对象,用于跨进程调用系统服务。
回到Instrumentation的代码中,这里是跨进程调用了系统服务ActivityTaskManagerService(ATMS)的startActivity
方法。
// Instrumentation类
int result = ActivityTaskManager.getService().startActivity(...args);
二、系统进程中
1. ActivityTaskManagerService(ATMS)
ActivityTaskManagerService是系统服务,用途是管理Activity及其容器类,如Task/Stack/Display等。ATMS是新版本加入分担AMS部分职责的类。
在ActivityTaskManagerService中,会依次调用startActivity -> startActivityAsUser。
在startActivityAsUser方法中,会通过Starter池获取到一个ActivityStarter对象,然后设置一些参数,最后调用execute
方法执行Activity的启动。
public final int startActivity(...args) {
return startActivityAsUser(...args);
}
private int startActivityAsUser(...args) {
return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
.setCaller(caller)
.setCallingPackage(callingPackage)
....
.execute();
}
2. ActivityStarter
顾名思义,ActivityStarter类就是为了启动Activity的。
在execute
方法中,会调用executeRequest
方法,这里会处理启动Activity的请求,并开始一个Activity启动的旅程(代码注释原话)。
executeRequest
方法会进行初步的检查并且确认权限,并且在这里组装对应Activity的ActivityRecord
,其包含了对应Activity的所有信息,并储存在任务栈帧TaskRecord
中。在Activity的启动过程中,Activity都是通过ActivityRecord来表示的。然后,会调用startActivityUnchecked
方法,接着startActivityUnchecked方法会调用startActivityInner
方法。
在startActivityInner
中,主要的一件事就是就是处理了Activity的启动模式,并且在ActivityStack
中处理对应Activity在任务栈中的相关事宜,包括但不仅限于将对应的ActivityRecord添加到TaskRecord中、将对应的ActivityRecord提到栈中最顶部。
最后,会调用RootWindowContainer的resumeFocusedStacksTopActivities
方法。
3. RootWindowContainer
RootWindowContainer是窗口容器(WindowContainer)的根容器,管理了所有窗口容器,设备上所有的窗口(Window)、显示(Display)都是由它来管理的。
顾名思义,resumeFocusedStacksTopActivities
会恢复对应任务栈顶部的Activity。这个方法会检查一些可见性相关的属性,然后转交给ActivityStack.resumeTopActivityUncheckedLocked
方法来继续流程。
4. ActivityStack
一个ActivityStack包含了若干个TaskRecord,每个TaskRecord又包含了若干个ActivityRecord,每个ActivityRecord对应了一个Activity。在这里,TaskRecord相当于在启动模式中的“任务栈”,根据启动模式的不同,在启动Activity的时候,会对TaskRecord进行不同的操作。
由于之前已经将对应Activity的ActivityRecord添加到了栈顶,所以resumeTopActivityUncheckedLocked
恢复的就是将启动的Activity。这个方法只是做一些判断,最后调用resumeTopActivityInnerLocked
实现具体功能。
在resumeTopActivityInnerLocked
方法中,做了一系列的判断,确保待启动的Activity可见性,预定Activity的切换动画等。
if (next.attachedToProcess()) {
...
} else {
...
mStackSupervisor.startSpecificActivity(next, true, true);
}
对于尚未启动的Activity来说,由于对应的Activity还没有添加到应用中,这里attachedToProcess
会返回false。所以接下来执行mStackSupervisor.startSpecificActivity
方法。
5. ActivityStackSupervisor
mStackSupervisor是ActivityStackSupervisor
类型的对象,主要作用是进行对ActivityStack的管理。根据注释所言,这个类在不久后将会被移除,虽然这个注释以及持续很多个版本了。
在ActivityStackSupervisor的startSpecificActivity
方法中,对于已经启动进程的Activity,会调用realStartActivityLocked
方法,看名字就知道这是真正的启动Activity了(若对应Activity的进程尚未启动,则会通过ATMS的startProcessAsync
方法启动进程,这就是另一个流程了)。
realStartActivityLocked
流程的核心代码如下:
final ClientTransaction clientTransaction = ClientTransaction.obtain(proc.getThread(), r.appToken);
clientTransaction.addCallback(LaunchActivityItem.obtain(...));
clientTransaction.setLifecycleStateRequest(ResumeActivityItem.obtain(...));
mService.getLifecycleManager().scheduleTransaction(clientTransaction);
在这里,mAtmService
对应的就是ActivityTaskManagerService,即ATMS;而getLifecycleManager
对应的类是ClientLifecycleManager
,通过其scheduleTransaction
方法将对应事务发送到App进程。
在这里,obtain
方法传入的proc.getThread()
,即是联系待启动Activity进程的Binder对象,之后会于系统服务进程和App进程的跨进程通信。
5. ClientLifecycleManager和Transaction
在开发中,transaction一般被翻译成“事务”,表示将要或正在进行的任务。在realStartActivityLocked
方法中,建立了一个事务,并将其递交给LifecycleManager。LivecycleManager和事务对应的类分别是ClientLifecycleManager
和ClientTransaction
,顾名思义就是用来管理客户端,即App进程的生命周期的。
看看ClientLifecycleManager的scheduleTransaction
方法和ClientTransaction的schedule
方法:
// ClientLifecycleManager.scheduleTransaction
void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
transaction.schedule();
}
// ClientTransaction.schedule
public void schedule() throws RemoteException {
mClient.scheduleTransaction(this);
}
可以看到,最终调用了ClientTransaction成员mClient
的scheduleTransaction
方法。这个mClient即是上一小节最后obtain
方法传入的Binder。
也就是说,在这里,通过mClient.scheduleTransaction
方法,系统服务进程将事务转发给了App进程。
三、回到App进程
1. ApplicationThread / ActivityThread
前面说到的mClient
对应的类是ActivityThread.ApplicationThread
。ActivityThread可以理解为一个应用的主线程(虽然它不是一个线程),应用的main
方法就是在这个类里面的,并通过Looper维持了应用的运行状态,这点在这篇文章中做了分析。
ApplicationThread
是ActivityThread的内部类,继承自IApplicationThread.Stub
,是一个Binder类,用于当前应用进程和系统进程之间的跨进程通信。
而ApplicationThread的scheduleTransaction
方法其实是调用了ActivityThread的同名方法。而ActivityThread自身并没有定义这个方法,而是继承自ClientTransactionHandler
来的。看下这个方法:
// ClientTransactionHandler
void scheduleTransaction(ClientTransaction transaction) {
transaction.preExecute(this);
sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}
// ActivityThread
private void sendMessage(int what, Object obj) {
Message msg = Message.obtain();
msg.what = what;
msg.obj = obj;
mH.sendMessage(msg);
}
所以scheduleTransaction
方法其实就是给ActivityThread内部HandlermH
发送了一个值为ActivityThread.H.EXECUTE_TRANSACTION
的消息,并把事务传递了过去。
而mH的处理方式就是把这个事务交给mTransactionExecutor
来执行。
2. TransactionExecutor
mTransactionExecutor
是一个TransactionExecutor
类型的对象,看名字就知道是专门用于处理事务的类。看看它的execute
方法:
public void execute(ClientTransaction transaction) {
...
executeCallbacks(transaction);
executeLifecycleState(transaction);
mPendingActions.clear();
}
public void executeCallbacks(ClientTransaction transaction) {
final List<ClientTransactionItem> callbacks = transaction.getCallbacks();
...
final int size = callbacks.size();
for (int i = 0; i < size; ++i) {
final ClientTransactionItem item = callbacks.get(i);
item.execute(mTransactionHandler, token, mPendingActions);
}
}
private void executeLifecycleState(ClientTransaction transaction) {
final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest();
...
cycleToPath(r, lifecycleItem.getTargetState(), true, transaction);
lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
}
逻辑很简单,就是分别调用了这个事务Callback和LifecycleState的execute
方法;另外就是调用了cycleToPath
方法,这个方法用于生命周期的过渡。
这里的在Callback和LifecycleState是在ActivityStackSupervisor的realStartActivityLocked
流程创建的,分别对应的是LaunchActivityItem
和ResumeActivityItem
。
看看这两个类的execute
方法:
// LaunchActivityItem
public void execute(...args) {
client.handleLaunchActivity(...args);
}
// ResumeActivityItem
public void execute(...args) {
client.handleResumeActivity(...args);
}
// cycleToPath
private void cycleToPath(...args) {
...
performLifecycleSequence(r, path, transaction);
}
private void performLifecycleSequence(...args) {
...
// 这里的state是ON_START
switch (state) {
...
case ON_START:
mTransactionHandler.handleStartActivity(r.token, mPendingActions);
}
}
而这里的client
参数和mTransactionHandler
是TransactionExecutor对象创建的时候就传入的,实际上都是是对应应用进程的ActivityThread
对象。
也就是说,到头来最终还是分别调用了ActivityThread的handleLaunchActivity
,handleStartActivity
和handleResumeActivity
方法。
3. ActivityThread
handleLaunchActivity
的核心是调用performLaunchActivity
方法。performLaunchActivity大体上依次做了这些事:
- 通过反射创建Activity实例,这是通过
Instrumentation.newActivity
方法实现的; - 通过Activity.attach方法,实例化Window对象;
- 调用Activity的onCreate回调;
在handleStartActivity
方法中,主要是通过Instrumentation调用了对应Activity的onStart和onRestoreInstanceState回调,并将状态设置为ON_START
;
与handleLaunchActivity类似的,handleResumeActivity
则是调用了performResumeActivity
方法。其大体上依次做了:
- 如果需要,调用待Resume Activity的onNewIntent、onActivityResult回调;
- 调用Activity的
performResume
方法,其中调用了onResume回调;
四、图示
点击查看原图