不止是“收纳盒”:从用户视角,解构 TaskRecord 作为“应用”的化身

293 阅读4分钟

一句话总结:

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,让它“自立门户”。

当一个 ActivityFLAG_ACTIVITY_NEW_TASK 模式启动时,ATMS 就会像一个“族长”一样,为它寻找合适的“家族”(TaskRecord):

  1. 寻找同姓家族: ATMS 会在所有现存的 TaskRecord 中,寻找一个 taskAffinity 与这个 Activity 的“姓氏”相匹配的。
  2. 加入家族: 如果找到了,ATMS 就会根据 singleTask 等规则,将 Activity 放入这个已存在的 TaskRecord 中。
  3. 创建新家族: 如果没找到,ATMS 就会为这个 Activity 创建一个全新的 TaskRecord,并以它的“姓氏”为这个新“家族”命名。

结论: taskAffinity 与启动模式的组合,共同决定了 Activity 在系统任务版图中的“归属”。


第三章:TaskRecord 在现代“单 Activity 架构”下的新角色

在 Google 推荐的“单 Activity”架构下,一个 App 可能只有一个 MainActivity。这意味着:

  • 内部导航简化: 应用内部的绝大多数界面跳转,都变成了 Fragment 的切换,发生在同一个 ActivityRecord 内部,与 TaskRecord 的复杂调度关系不大。
  • 角色转变: TaskRecord 的知识,对现代开发者而言,其意义从“管理内部 Activity 跳转”,转变为**“管理应用作为一个整体,与外部世界交互时的表现”**。

你仍然需要关心 TaskRecord 的场景:

  1. 从外部启动: 当你的 Activity 被其他应用(如浏览器、文件管理器)通过带有 FLAG_ACTIVITY_NEW_TASKIntent 启动时,它的行为将由 taskAffinity 和启动模式决定。
  2. 对外分享: 当你的应用启动其他应用的 Activity 时(如分享到微信),你需要理解你是在为微信的 TaskRecord 添加内容,还是在创建一个新的 TaskRecord
  3. 定义应用的入口:Activity 通常被设为 singleTask,就是为了确保它作为其 TaskRecord 的根,维护一个清晰的应用入口。

四、总结:从“收纳盒”到“应用化身”的认知升级

理解 TaskRecord,需要具备三个层面的认知:

  1. 数据结构层面: 它是一个后进先出的、包含 ActivityRecord 的堆栈。
  2. 用户体验层面: 它是用户在“最近任务”界面看到的、可交互的“应用卡片”。
  3. 架构设计层面: 它是系统通过 taskAffinity 和启动模式,为一组关联的 Activity 定义的“逻辑单元”。

在单 Activity 架构成为主流的今天,TaskRecord 的概念并未过时,而是回归了它的本质——作为操作系统中“任务”的最小管理单元,定义了你的应用在 Android 多任务世界中的身份和行为。