第六章 理解 ActivityManagerService.md

何言 2021年10月22日 56次浏览

6.1 AMS 家族

Android 8.0 与 Android 7.0 的 AMS 相关处理有区别。主要是使用了 AIDL 重写了 IPC 部分 这里分别介绍。

6.1.1 Android 7.0 的 AMS 家族

image20211001134803278.png

image20211001135116837.png

6.1.2 Android 8.0 的 AMS 家族

Android 8.0 去掉了 AMP,直接使用 AIDL 实现 IPC:

image20211001135416354.png

6.2 AMS 的启动过程(PASS)

6.3 AMS 与应用进程

  • 启动应用程序时 AMS 会检查这个应用程序需要的应用程序进程是否存在
  • 如果需要的应用程序进程不存在,AMS 就会请求 Zygote 进程创建需要的应用进程

6.4 AMS 重要的数据结构

6.4.1 解析 ActivityRecord

ActivityRecord 记录了一个 Activity 的所有信息,用来描述一个 Activity,在 ActivityStarter 的 startActivity 方法中创建的。以下是其重要成员变量

image20211002152617131.png

6.4.2 解析 TaskRecord

TaskRecord 用来描述一个 Activity 任务栈,其内部也有许多成员变量,这里同样给出比较重要的部分成员变量:

image20211002152853019.png

image20211002152935576.png

TaskRecord 储存了一个任务栈的所有信息,包括其唯一标识符、倾向性、Activity 记录和 AMS 引用等。其中含有 ActivityStack 对象,为当前 TaskRecord 所归属的 ActivityStack 。

6.4.3 解析 ActivityStack

ActivityStack 虽然叫 Stack ,但其不是 栈 数据结构(或者说不单纯是栈),ActivityStack 是一个管理类,用来管理所有 Activity。其内部维护了 Activity 的所有状态、特殊状态的 Activity 以及和 Activity 相关的列表等数据 。ActivityStack 是由 ActivitStackSupervisor 来进行管理的,而 ActivityStackSupervisor 在 AMS 的构造方法中被创建。

  1. ActivityStack 的实例类型

    ActivityStackSupervisor 中有许多 ActivityStack 实例,如下:

    public class ActivityStackSupervisor extends ConfigurationContainer implements DisplayListener{
        // ……
    
        // 存储 Launcher App 的所有 Activity
        ActivityStack mHomeStack;
    
        // 当前正在接收输入或启动下一个 Activity 的所有 Activity (焦点)
        ActivityStack mFocusedStack;
    
        // 此前接收输入的所有 Activity
        private ActivityStack mLashFocusedStack;
    
        // ……
    }
    
    
  2. ActivityState

    该类是一个枚举类,用来枚举 Activity 的所有状态:

    enum ActivityState{
        INITIALIZING,
        RESUMED,
        PAUSING,
        PAUSED,
        STOPPING,
        STOPPED,
        FINISHING,
        DESTROYING,
        DESTROYED
    }
    
  3. 特殊状态的 Activity

    有一些 Activity 处于临时的特殊状态,在 ActivityStack 中使用了一些变量来保存这些特殊状态的 Activity

    ActivityRecord mPausingActivity = null; // 正在暂停的 Activity
    ActivityRecord mLashPausedActivity = null; // 上一个已经被暂停的 Activity
    ActivityRecord mLashNoHistoryActivity = null; // 最近一次没有历史记录的 Activity
    ActivityRecord mResumedActivity = null; // 已经 Resume 的 Activity
    ActivityRecord mLastStartedActivity = null; // 最近一次启动的 Activity
    // 传递给 converTranslucent 方法的最上层的 Activity
    ActivityRecord mTranslucentActivityWaiting = null;
    
  4. 维护的 ArrayList

    ActivityStack 中维护了许多 ArrayList,其中的类型主要是 ActivityRecord 和 TaskRecord 如图:

image20211002154923815.png

6.5 Activity 栈管理

6.5.1 Activity 任务栈模型

image20211002155756814.png

6.5.2 Launch Mode

  • standerd
  • singleTop
  • singleTask
  • singleInstance

具体可参考 Android 开发艺术探索笔记

6.5.3 Intent 的 FLAG

  • FLAG_ACTIVITY_SINGLE_TOP
  • FLAG_ACTIVITY_NEW_TASK
  • FLAG_ACTIVITY_CLEAR_TOP

以下 FALG 与启动模式无关,是 Activity 启动时会自动分析加入(也可手动加入)

  • FLAG_ACTIVITY_NO_HISTORY 一旦退出,就不存在于栈中
  • FLAG_ACTIVITY_MULTIPLE_TASK 与 NEW_TASK 一起使用时会启动一个新的栈来启动
  • FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS 不会被放入最近启动的 Activity 列表中
  • FLAG_ACTIVITY_BROUGHT_TO_FRONT 当启动模式为 singleTask 时,由系统自动加上
  • FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY 从历史记录中启动的 Activity 会有该标记
  • FLAG_ACTIVITY_CLEAR_TASK 当与 NEW_TASK 一起使时会清除与启动 Activity 相关栈的所有其他 Activity

注意,最终影响 Activity 启动的只有 Intent 中的 FALG,四种启动模式中只是自动加入了对应的 FLAG,可能一种模式对应多个 FLAG 。

6.5.4 taskAffinity

taskAffinity 代表 Activity 希望归属的栈,默认情况下,一个应用程序的所有 Activity 都有相同的 taskAffinity。有以下两种情况下自定义 taskAffinity 会有影响

  1. 与 FALG_ACTIVITY_NEW_TASK 或 singleTask 配合,如果新启动的 Activity 的 taskAffinity 和栈 taskAffnity 相同则加入到该栈中(该栈可加入),如果不同,则会创建新栈。
  2. 与 allowTaskPeparenting 配合,如果 allowTaskPeparenting 为 true,说明该 Activity 具有转移能力 。当你的 activity 被其它 app 中采用隐式 intent 启动的时候,实际上是加入其他 app 中对应栈中。如果该 activity 具有转移能力,则在后台中如果与该 activity 相容的 栈出现,则会直接将 activity 转移到新的那个相容的栈中,这里相容的栈会受到 taskAffinity 影响。

6.6 小结

本章设计 AMS 家族,AMS 启动,AMS 重要数据结构与 Activity 栈管理 。