Activity 为开发者最常接触和使用的系统基础组件,这注定了 Activity 启动的流程整体较为复杂,每个 Android 系统版本都会对 Activity 的启动过程做一定的优化和重构,但核心的流程思路是一致。本文继续以 Android 11 的代码为基础,详解 Activity 的启动流程。
ActivityTaskManager 发起 startActivity 请求
在 Android 10 以前,包含 Activity 在内的四大组件的启动与管理,都是通过系统服务 ActivityManagerService 来负责。而从 Android 10 开始,Activity 的这部分抽离了出来,改到了在新的 ActivityTaskManagerService 中来处理。
与其他常用的系统服务一样,应用进程内也有相应的 ActivityTaskManager 和 ActivityTaskManagerService 对应,两者间通过 Binder
完成 IPC 通信。
启动一个新的 Activity 从 startActivity()
方法开始,逐步调用到 ActivityTaskManager 发起通信:
frameworks/base/core/java/android/app/
- Activity.java
- Instrumentation.java
- IActivityTaskManager.aidl
- ActivityTaskManager.java
frameworks/base/services/core/java/com/android/server/wm/
- ActivityTaskManagerService.java
其中实现的 Binder
通信对应的 aidl 文件为 IActivityTaskManager.aidl:
interface IActivityTaskManager {
int startActivity(in IApplicationThread caller, ..., in Intent intent, ...);
...
}
ActivityTaskManager 内持有一个单例实现为 IActivityTaskManager 接口的 client 端实现,代码示例如下:
@SystemService(Context.ACTIVITY_TASK_SERVICE)
public class ActivityTaskManager {
...
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);
}
};
...
}
而 ActivityTaskManagerService 运行在系统服务 system_server
进程,作为 IActivityTaskManager 接口的 server 端。
Activity 任务逻辑处理
其后在 ActivityTaskManagerService 中进一步通过 ActivityStarter 来处理目标 Activity 的启动逻辑,流程如下:
frameworks/base/services/core/java/com/android/server/wm/
- ActivityStarter.java
- ActivityRecord.java
- ActivityStack.java
在 ActivityStarter 中会创建一个用于在系统服务中描述当前 Activity 的 ActivityRecord
对象,其包含了如 token、Activity 的状态、intent 等各类信息,是系统服务层面用于记录 Activity 相关的各种操作后的核心对象。
在 ActivityStarter 的 startActivityInner()
方法中,完成了一系列与 Activity 任务相关的关键操作:
singleTop
或singleTask
启动模式下,Intent 标志统一带上FLAG_ACTIVITY_NEW_TASK
;
- 查找是否有可复用的 Activity 任务(ActivityStack 对象),若没有则按需创建新的任务;
- 在前台的任务的栈顶 Activity 是否刚好为要启动的 Activity 的实例,若是且启动模式为
singleTop
orsingleTask
或者启动 Intent 标志带有FLAG_ACTIVITY_SINGLE_TOP
,通知已有栈顶实例回调onNewIntent()
,本次启动不再创建新 Activity 实例。
换言之,依据启动模式和 Intent 标志,并不是每次调用 startActivity()
都会启动并创建新的 Activity 实例。
启动新的 Activity
我们先看下会创建新的 Activity 实例往下的调用链路。
frameworks/base/services/core/java/com/android/server/wm/
- RootWindowContainer.java
- ActivityStackSupervisor.java
ActivityStackSupervisor,原意设计为管理、处理系统中的各个 ActivityStack 对象。从 Android 10 开始,引入了 RootWindowContainer 表示整个设备的根窗口容器,逐步承担并替换部分 ActivityStackSupervisor 的职责。
在上面的调用栈,最终通过 ActivityStackSupervisor 的 realStartActivityLocked()
真正执行新 Activity 实例的启动。
从 ActivityTaskManagerService 开始,以上执行的流程都发生在系统服务进程中。其后,会通知到应用进程负责创建 Activity 实例对象,回调生命周期等一系列操作。该跨进程通信的过程同样是通过 Binder 实现:
frameworks/base/services/core/java/com/android/server/wm/
- ClientLifecycleManager.java
frameworks/base/core/java/android/app/servertransaction/
- ClientTransaction.java
- LaunchActivityItem.java
- ResumeActivityItem.java
frameworks/base/bin/main/android/app/
- IApplicationThread.aidl
上面,Android Framework 引入了额外的可序列化对象 ClientTransaction 类用来包含一系列的消息事件发送到到应用进程来处理。其运作的原理是:
- 在系统服务进程中,创建多个可序列化的 ClientTransactionItem 对象,每个对象代表一个具体要处理的消息事件,并添加到 ClientTransaction 内;
- ClientTransaction 内持有 IApplicationThread 的 BinderProxy 对象,调用其
scheduleTransaction()
方法实现 Binder 跨进程通信,复制自身对象数据(包括其内的各个 ClientTransactionItem)到应用进程的 ActivityThread 中; - ActivityThread 进一步把 ClientTransaction 对象分发至 TransactionExecutor 来处理,其会分别执行各个 ClientTransactionItem 对象实现的回调方法来完成事件的处理。
IApplicationThread 的 BinderProxy 对象由 ActivityTaskManagerService 的
startActivity()
方法传入
frameworks/base/core/java/android/app/servertransaction/
- TransactionExecutor.java
在 Activity 启动这一流程中,ClientTransaction 共添加了两个 ClientTransactionItem:LaunchActivityItem 和 ResumeActivityItem,分别对应 Activity 生命周期中的 onCreate()
和 onResume()
行为。实际上,Activity 生命周期中的大部分回调都有对应的 item:
生命周期 | ClientTransactionItem 子类 |
---|---|
ON_CREATE |
LaunchActivityItem |
ON_START |
StartActivityItem |
ON_RESUME |
ResumeActivityItem |
ON_PAUSE |
PauseActivityItem |
ON_STOP |
StopActivityItem |
ON_DESTROY |
DestroyActivityItem |
小结一下,Android 启动的主流程中,在系统服务进程和应用进程之间共进行两次 Binder IPC 通信,其 Client / Server 端对应关系如下:
在第二次的 Binder IPC 通信中,ClientTransaction 对象的流转过程如下:
Activity 生命周期的回调
正常一个新 Activity 的启动,其生命周期的回调理应是:
而在上文的讲述的 ClientTransaction 对象中只带有 LaunchActivityItem 和 ResumeActivityItem,其各自的回调只会执行到 “onCreate
” 和 “onResume
” 这两个链路,把中间缺少的 “onStart
” 是怎么来的呢?
这里,Android 系统引入了 TransactionExecutorHelper 类来对将要执行的 Activity 生命周期做梳理:只需要传入此次 Transaction 任务的开始和结束状态,依据 Activity 生命周期的顺序,自动补上中间的状态。
比如在 Activity 的启动过程中,开始状态为 ON_CREATE
,结束状态 ON_RESUME
,则会补充上中间的 ON_START
。Activity 完整生命周期的顺序在 ActivityLifecycleItem
中有定义:
public abstract class ActivityLifecycleItem extends ClientTransactionItem {
...
public static final int UNDEFINED = -1;
public static final int PRE_ON_CREATE = 0;
public static final int ON_CREATE = 1;
public static final int ON_START = 2;
public static final int ON_RESUME = 3;
public static final int ON_PAUSE = 4;
public static final int ON_STOP = 5;
public static final int ON_DESTROY = 6;
public static final int ON_RESTART = 7;
...
}
frameworks/base/core/java/android/app/servertransaction/
- TransactionExecutorHelper.java
- ActivityLifecycleItem.java
最后,整理一下启动过程中,Activity 各个生命周期的调用链路,流程大致上都是一致的:
onCreate()
方法的回调流程:
onStart()
方法的回调流程:
onResume()
方法的回调流程:
至此,一个新 Activity 的完整启动流程梳理完毕。