一句话总结:
TaskRecord 不仅是 Activity 的“收纳盒”,更是用户在**“最近任务”界面看到的每一个“应用卡片”**在系统内部的真实化身。理解它,就是理解 Android 多任务切换的本质。
第一章:连接两个世界——TaskRecord 与用户眼中的“应用”
在开始技术剖析前,我们先建立一个核心认知:
- 在用户世界里,用户通过“最近任务”按钮,看到的是一叠可以切换和关闭的“应用卡片”。
- 在系统世界(
ActivityTaskManagerService中),每一张“应用卡片”,都对应着一个TaskRecord对象。
TaskRecord 是系统用来封装和管理一个连贯的用户任务(比如“发一条朋友圈”、“网购一件商品”)的容器。你对卡片的操作,就是对 TaskRecord 的操作。
| 用户操作 | 系统内部对 TaskRecord 的操作 |
|---|---|
| 点击桌面图标启动微信 | ATMS 为微信创建一个新的 TaskRecord |
| 按 Home 键 | ATMS 将微信的 TaskRecord 移动到后台 |
| 在“最近任务”中切回微信 | ATMS 将微信的 TaskRecord 重新移动到前台 |
| 在“最近任务”中划掉微信卡片 | ATMS 销毁微信的 TaskRecord 及其包含的所有 ActivityRecord |
第二章:TaskRecord 的内部——Activity 的“家族谱系”
TaskRecord 内部,是一个 ActivityRecord 的堆栈,后进先出。但决定哪个 Activity 应该进入哪个 TaskRecord 的,是它们的“血缘关系”。
核心机制:android:taskAffinity (任务亲和性)
taskAffinity 是定义在 AndroidManifest.xml 中,赋予 Activity 的一个“姓氏”。
- 默认姓氏: 默认情况下,同一应用的所有
Activity都“姓”同一个姓,即应用的包名。 - 指定姓氏: 你可以为某个
Activity指定一个独特的taskAffinity,让它“自立门户”。
当一个 Activity 以 FLAG_ACTIVITY_NEW_TASK 模式启动时,ATMS 就会像一个“族长”一样,为它寻找合适的“家族”(TaskRecord):
- 寻找同姓家族:
ATMS会在所有现存的TaskRecord中,寻找一个taskAffinity与这个Activity的“姓氏”相匹配的。 - 加入家族: 如果找到了,
ATMS就会根据singleTask等规则,将Activity放入这个已存在的TaskRecord中。 - 创建新家族: 如果没找到,
ATMS就会为这个Activity创建一个全新的TaskRecord,并以它的“姓氏”为这个新“家族”命名。
结论: taskAffinity 与启动模式的组合,共同决定了 Activity 在系统任务版图中的“归属”。
第三章:TaskRecord 在现代“单 Activity 架构”下的新角色
在 Google 推荐的“单 Activity”架构下,一个 App 可能只有一个 MainActivity。这意味着:
- 内部导航简化: 应用内部的绝大多数界面跳转,都变成了
Fragment的切换,发生在同一个ActivityRecord内部,与TaskRecord的复杂调度关系不大。 - 角色转变:
TaskRecord的知识,对现代开发者而言,其意义从“管理内部Activity跳转”,转变为**“管理应用作为一个整体,与外部世界交互时的表现”**。
你仍然需要关心 TaskRecord 的场景:
- 从外部启动: 当你的
Activity被其他应用(如浏览器、文件管理器)通过带有FLAG_ACTIVITY_NEW_TASK的Intent启动时,它的行为将由taskAffinity和启动模式决定。 - 对外分享: 当你的应用启动其他应用的
Activity时(如分享到微信),你需要理解你是在为微信的TaskRecord添加内容,还是在创建一个新的TaskRecord。 - 定义应用的入口: 主
Activity通常被设为singleTask,就是为了确保它作为其TaskRecord的根,维护一个清晰的应用入口。
四、总结:从“收纳盒”到“应用化身”的认知升级
理解 TaskRecord,需要具备三个层面的认知:
- 数据结构层面: 它是一个后进先出的、包含
ActivityRecord的堆栈。 - 用户体验层面: 它是用户在“最近任务”界面看到的、可交互的“应用卡片”。
- 架构设计层面: 它是系统通过
taskAffinity和启动模式,为一组关联的Activity定义的“逻辑单元”。
在单 Activity 架构成为主流的今天,TaskRecord 的概念并未过时,而是回归了它的本质——作为操作系统中“任务”的最小管理单元,定义了你的应用在 Android 多任务世界中的身份和行为。