一、ActivityRecord:Activity 的 “数字档案”
在 Android 系统中,ActivityRecord是 ActivityManagerService(AMS)用于管理 Activity 实例的核心数据结构,可视为 Activity 在系统层面的 “数字档案”。它不直接参与界面渲染,而是专注于记录 Activity 的关键信息,协调其与任务栈、进程及系统服务的交互。
1. 核心属性:档案里的关键信息
| 属性名 | 作用描述 |
|---|---|
app | 指向所属进程记录(ProcessRecord),记录 Activity 运行的进程信息(如进程名、UID)。 |
task | 指向所属任务栈(TaskRecord),标识 Activity 属于哪个任务(如浏览器的多个标签页)。 |
info | 存储 Manifest 中声明的元数据(如android:launchMode、权限、主题)。 |
state | 生命周期状态(如RESUMED/PAUSED/STOPPED),由 AMS 根据用户操作或系统事件更新。 |
appToken | 跨进程通信令牌(继承自IApplicationToken.Stub),用于与窗口管理服务(WMS)交互窗口状态。 |
realActivity | 组件名(如com.example.App.MainActivity),标识具体的 Activity 类。 |
状态机示例:
- 当用户打开新 Activity 时,旧 Activity 状态从
RESUMED变为PAUSED,新 Activity 状态变为RESUMED。 - 当 Activity 被用户按返回键关闭时,状态依次经过
FINISHING→DESTROYING→DESTROYED。
2. 与 TaskRecord 的关系:任务栈中的 “任务卡片”
TaskRecord代表一个 “任务栈”(如手机的 “最近任务” 列表中的一个条目),用于管理一组相关 Activity(如浏览器的主页、搜索页、详情页)。
-
层级关系:一个
TaskRecord包含多个ActivityRecord,按启动顺序组成后进先出(LIFO)的栈结构。 -
核心作用:
- 维护 Activity 的启动顺序,支持返回键回退逻辑。
- 根据启动模式(如
singleTask)决定是否复用已有 Activity 或创建新实例。 - 通过
affinity属性定义任务栈的 “亲和性”(如指定某个任务栈属于特定用户或应用)。
二、ActivityStack 与 ActivityStackSupervisor:栈结构的管理者
1. ActivityStack:Activity 的物理容器
作用:
-
管理一个或多个
TaskRecord,负责 Activity 的栈内调度(如栈顶 Activity 的恢复、暂停、移除)。 -
维护栈内 Activity 的状态一致性,例如确保同一时刻只有一个 Activity 处于
RESUMED状态。
核心属性:
-
mResumedActivity:当前栈顶可见的 Activity(状态为RESUMED)。 -
mLastPausedActivity:最近一次暂停的 Activity(状态为PAUSED)。 -
mTaskHistory:存储该栈包含的所有TaskRecord,按任务创建顺序排列。
关键操作:
-
resumeTopActivityLocked:恢复栈顶 Activity,触发其onResume回调,并暂停其他 Activity。 -
startPausingLocked:暂停当前 Activity,触发onPause回调,为新 Activity 启动做准备。 -
removeActivityLocked:从栈中移除 Activity,触发onDestroy回调(如用户按返回键关闭 Activity)。
示例场景:
当用户从 Activity A 启动 Activity B 时:
- ActivityStack 调用
startPausingLocked暂停 A(状态变为PAUSING)。 - 创建 Activity B 的
ActivityRecord并加入栈顶。 - 调用
resumeTopActivityLocked恢复 B(状态变为RESUMED),A 最终变为PAUSED状态。
2. ActivityStackSupervisor:全局栈调度中心
作用:
-
管理系统中所有
ActivityStack(如主屏幕栈、应用栈、多窗口栈),协调不同栈之间的切换(如从主屏幕切换到最近任务)。 -
处理多显示设备(如折叠屏、外接显示器)场景,为每个显示设备维护独立的
ActivityDisplay和栈结构。
核心属性:
mFocusedStack:当前获得焦点的栈(用户正在交互的栈)。mHomeStack:主屏幕栈,存储桌面 Activity(如 Launcher)。mActivityDisplays:按显示设备 ID(displayId)映射的ActivityDisplay,支持多屏独立显示不同栈。
三、Activity 栈关系:从单体到层级的管理架构
1. 栈结构的层级关系
Android 通过多层数据结构实现对 Activity 的高效管理,形成 “Supervisor → Display → Stack → Task → Activity” 的层级链:
-
ActivityStackSupervisor:
作为全局管理者,负责协调所有显示设备(如手机主屏、外接显示器)的 Activity 栈。-
核心作用:维护
mActivityDisplays(按显示设备 ID 映射),每个显示设备对应一个ActivityDisplay。 -
默认栈:
mHomeStack:主屏幕栈,存储桌面 Activity(如 Launcher),栈 ID 固定为 0。mFocusedStack:当前用户交互的栈(如正在使用的应用栈)。
-
-
ActivityDisplay:
代表一个物理或虚拟显示设备(如折叠屏的不同分屏),包含一组ActivityStack。- 单设备场景:默认只有一个
ActivityDisplay,包含Home Stack(桌面)和App Stack(应用栈)。 - 多设备场景:每个显示器独立管理自己的栈,如主屏显示社交应用,副屏显示视频应用。
- 单设备场景:默认只有一个
-
ActivityStack:
具体的物理栈,存储同一显示设备中的任务栈(TaskRecord)。-
核心属性:
mResumedActivity:栈顶可见的 Activity(状态为RESUMED)。mTaskHistory:按创建顺序排列的任务栈列表,支持任务切换(如最近任务列表)。
-
-
TaskRecord:
逻辑任务单元,包含一组相关 Activity(如同一应用的多个页面)。-
核心逻辑:
- 按启动模式(如
singleTask)决定是否复用栈内 Activity。 - 通过
affinity属性定义任务归属(如指定任务属于某个用户或应用)。
- 按启动模式(如
-
-
ActivityRecord:
单个 Activity 的系统记录,关联到所属的TaskRecord和ActivityStack。- 反向引用链:
ActivityRecord.task → TaskRecord.stack → ActivityStack.mStackSupervisor → ActivityStackSupervisor
便于系统从 Activity 快速回溯到全局管理节点。
- 反向引用链:
2. 典型场景:单设备下的栈结构
-
默认配置:
plaintext
ActivityStackSupervisor ├─ ActivityDisplay (displayId=0) │ ├─ HomeStack (stackId=0, 桌面Activity) │ └─ AppStack (stackId=1, 应用Activity) │ └─ TaskRecord (taskId=1, 包含Activity A、B、C) │
四、Activity 启动与停止流程:状态机与系统调度
1. 启动流程:从点击到界面显示的全链路
当用户触发startActivity(如点击按钮)时,系统通过以下步骤完成 Activity 的启动和界面显示:
步骤 1:客户端发起请求
-
调用链:
Activity.startActivity() → ContextImpl.startActivity() → AMP.startActivity()(通过 Binder 调用 AMS)。 -
关键操作:
- 封装启动参数(如 Intent、调用者信息),通过 Binder 传递给系统服务 AMS。
步骤 2:AMS 调度任务栈
-
核心方法:
AMS.startActivityLocked() → ActivityStackSupervisor.resumeTopActivityInnerLocked() -
逻辑解析:
- 查找或创建任务栈:根据 Activity 的启动模式(如
singleTask)和亲和性(taskAffinity)确定所属任务栈(TaskRecord)。 - 暂停旧 Activity:若栈顶存在其他 Activity(如 Activity A),调用
startPausingLocked()将其状态设为PAUSING,触发onPause回调。 - 创建新 ActivityRecord:生成
ActivityRecord对象,记录启动参数、所属进程和任务栈。
- 查找或创建任务栈:根据 Activity 的启动模式(如
步骤 3:启动目标进程(若需要)
-
场景:若目标 Activity 所属进程未运行(如首次启动应用),AMS 通过
startProcessLocked()请求 Zygote 创建新进程。 -
进程通信:
- 新进程启动后,通过
ActivityThread.attach()与 AMS 建立 Binder 连接(ATP.bindApplication)。 - AMS 通过
realStartActivityLocked()通知新进程加载 Activity,调用scheduleLaunchActivity()发送启动消息。
- 新进程启动后,通过
步骤 4:App 进程执行生命周期回调
-
Handler 消息驱动:
新进程的主线程 Handler(H)收到H.LAUNCH_ACTIVITY消息,触发以下操作:- 创建 Activity 实例:通过反射调用
Instrumentation.newActivity()创建 Activity 对象。 - 关联上下文:调用
activity.attach()绑定ContextImpl和appToken,初始化窗口管理器(WMS)。 - 生命周期回调:依次调用
onCreate()→onStart()→onResume(),界面渲染完成后状态变为RESUMED。
- 创建 Activity 实例:通过反射调用
步骤 5:更新栈状态与用户可见性
-
AMS 最终处理:
- 调用
activityIdleInternalLocked()标记
- 调用