Android 核心大管家 ActivityManagerService (AMS)

我们把这篇关于 Android 核心大管家 ActivityManagerService (AMS) 启动和运作的文章,变成一个发生在「安卓王国」里的故事,结合代码,让它更容易理解。

​故事梗概:​​ 想象一个庞大的安卓王国(你的手机)。这个王国需要一个超级大管家(AMS)来管理所有居民(App)、协调资源、确保一切有序运行。这个故事讲的就是这个大管家如何被任命上岗(启动),以及它如何指挥居民区的建立(进程启动)和家族成员如何分工协作的。

​核心角色:​

  • ​国王 (Linux Kernel):​ 最底层的统治者,负责土地、资源分配(硬件)。
  • ​王宫总管 (init 进程):​ 国王的第一个臣子,负责启动其他重要官员。
  • ​育婴堂负责人 (Zygote 进程):​ 负责按需"孕育"出新的居民区(App 进程)。
  • ​王宫核心 (SystemServer 进程):​ 国王最重要的行政中心,里面住着各种关键大臣(系统服务)。
  • ​大管家 - AMS (ActivityManagerService):​ 我们的主角,住在王宫核心里,管理王国居民。
  • ​大管家助手 (ActivityManager):​ 普通居民(App)接触到的"前台",它负责把居民的请求转告给真正的、住在王宫深处的大管家(AMS)。
  • ​信使系统 (Binder IPC):​ 王国里的高效通信网络,用于王宫内部以及王宫与居民区之间的消息传递。

​第一幕:王宫启动,任命大管家 (AMS 启动流程)​

  1. ​国王登基 (Bootloader -> Kernel):​​ 手机开机,硬件通电,国王(Linux Kernel)掌握大权。

  2. ​任命总管 (init 进程):​ ​ 国王任命了第一位大臣------王宫总管(init 进程)。

  3. ​总管启动核心 (init -> Zygote / SystemServer):​ ​ 总管根据王国的宪法(init.rc 脚本),启动了两个极其重要的机构:

    • ​育婴堂 (Zygote 进程):​ 稍后再讲它的作用。
    • ​王宫核心 (SystemServer 进程):​ 这是王国真正的行政心脏,所有核心系统服务都在这里运行。我们的故事重点发生在这里。
  4. ​王宫核心开张 (SystemServer.main()):​

    scss 复制代码
    java
    Copy
    // frameworks/base/services/java/com/android/server/SystemServer.java
    public static void main(String[] args) {
        new SystemServer().run(); // 王宫核心开始运转!
    }
    private void run() {
        // 加载核心装备库 (相当于给王宫核心配备标准工具)
        System.loadLibrary("android_servers"); // ①
        // 任命服务大臣总管 (SystemServiceManager - SSM)
        mSystemServiceManager = new SystemServiceManager(mSystemContext); // ②
        // 正式启动关键大臣们(系统服务)
        try {
            startBootstrapServices(); // ③ 启动最重要的基础大臣,包括大管家AMS
            startCoreServices();      // ④ 启动核心功能大臣
            startOtherServices();     // ⑤ 启动其他辅助大臣
        } catch (...) { ... }
    }
    • ​① System.loadLibrary("android_servers"):​ 相当于给 SystemServer 这个王宫核心加载了标准工具库,里面包含了各种系统服务需要的"武功秘籍"。
    • ​② new SystemServiceManager(mSystemContext):​ 任命了 ​服务大臣总管 (SSM - SystemServiceManager)​ 。它的职责就是管理所有大臣(系统服务)的生命周期:创建他们、通知他们上岗 (onStart)、通知他们王国状态变化 (onBootPhase)。
    • ​③ startBootstrapServices():​ 启动王国最基础、最核心的大臣们,没有他们王国就转不起来。​我们的大管家 AMS 就在这里被任命!​
  5. ​任命大管家 AMS (startBootstrapServices()):​

    csharp 复制代码
    java
    Copy
    // frameworks/base/services/java/com/android/server/SystemServer.java
    private void startBootstrapServices() {
        // ... 可能先启动安装大臣 (Installer) ...
        // 重中之重:启动大管家AMS!通过服务大臣总管(SSM)
        mActivityManagerService = mSystemServiceManager.startService(
                ActivityManagerService.Lifecycle.class).getService(); // ★ 关键点 ★ ①
        // 告诉AMS谁在管理大臣们 (SSM)
        mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
        // ... 可能给AMS配置其他工具 (如Installer) ...
    }
    • ​★ 关键点 ★ ① mSystemServiceManager.startService(ActivityManagerService.Lifecycle.class):​ ​ 服务大臣总管 (SSM) 接到命令:"启动一个 ActivityManagerService.Lifecycle 类型的服务大臣"。SSM 怎么做的呢?它有一套标准流程:

      kotlin 复制代码
      java
      Copy
      // frameworks/base/services/core/java/com/android/server/SystemServiceManager.java
      public <T extends SystemService> T startService(Class<T> serviceClass) {
          // 1. 找到大臣的"出生证明"(构造函数)
          Constructor<T> constructor = serviceClass.getConstructor(Context.class); // ①
          // 2. 让大臣出生(实例化) - 这里传入的是 ActivityManagerService.Lifecycle.class
          T service = constructor.newInstance(mContext); // ②
          // 3. 登记注册大臣 (加入大臣名册)
          mServices.add(service); // ③
          // 4. 通知大臣:"你可以开始履行你的职责了!" (调用 onStart())
          service.onStart(); // ④
          return service; // 把新大臣返回给调用者
      }
      • serviceClassActivityManagerService.Lifecycle.class 时:

        • ​② constructor.newInstance(mContext):​ ​ 这会调用 Lifecycle 的构造函数:

          scala 复制代码
          java
          Copy
          // frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
          public static final class Lifecycle extends SystemService {
              private final ActivityManagerService mService; // 真正的大管家
              public Lifecycle(Context context) {
                  super(context);
                  // ★ 关键点 ★ ② 在这里,真正的大管家 AMS 诞生了!
                  mService = new ActivityManagerService(context);
              }
              @Override
              public void onStart() {
                  // ★ 关键点 ★ ③ 通知大管家 AMS:"你可以开始管理王国了!"
                  mService.start();
              }
              public ActivityManagerService getService() {
                  return mService; // 获取真正的大管家实例
              }
          }
        • ​④ service.onStart():​ ​ 触发 Lifecycle.onStart(),进而调用 mService.start(),这就是大管家 AMS 正式上岗的信号!AMS 会在这里进行各种初始化设置,准备好管理王国。

      • ​① 返回后的 .getService():​startBootstrapServices() 里通过 .getService() 拿到了 Lifecycle 内部持有的真正的 ActivityManagerService 实例 (mService),并赋值给 SystemServermActivityManagerService 变量。​​至此,王宫核心 (SystemServer) 拥有了它的大管家 (AMS) 的引用。​

  6. ​大管家就位:​ ​ AMS 在 SystemServer 进程中创建、初始化、启动完成。它现在知道王国里有哪些资源,知道服务大臣总管 (SSM),也知道育婴堂 (Zygote) 的位置(稍后用到)。它准备好接收命令,管理王国了!


​第二幕:居民区的建立 - AMS 与进程启动​

大管家 AMS 上岗后,它的核心职责之一就是:​​当有新的居民(App)想住进王国,或者已有的居民需要更多空间(启动新组件)时,确保这些居民有地方住(有进程运行)。​

  1. ​居民申请入住 (启动 Service):​ ​ 想象一个居民(比如微信)想启动一个后台服务(比如位置服务)。微信自己已经有一个居民区(主进程),但它可能需要为这个服务单独开辟一个区域(新进程,如果服务声明了 android:process)。

  2. ​管家检查 (bringUpServiceLocked):​ ​ 王国负责管理服务的部门 (ActiveServices) 收到申请。它会请示大管家 AMS:

    typescript 复制代码
    java
    Copy
    // frameworks/base/services/core/java/com/android/server/am/ActiveServices.java
    private String bringUpServiceLocked(ServiceRecord r, ...) {
        // 1. 查看申请单:这个服务需要住在哪个居民区?(进程名)
        final String procName = r.processName; // 例如 "com.tencent.mm:location"
        ProcessRecord app;
        if (!isolated) {
            // 2. 询问大管家 AMS:"王国里已经存在叫 'com.tencent.mm:location' 的居民区吗?"
            app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false); // ②
            if (app != null && app.thread != null) {
                // 3. 居民区存在且活跃!直接在这个区启动服务就行。
                realStartServiceLocked(r, app, execInFg); // ④
                return null;
            }
        }
        if (app == null && ...) {
            // 5. 哎呀,这个居民区还不存在!
            // 6. 紧急呼叫大管家 AMS:"请火速创建一个叫 'com.tencent.mm:location' 的居民区!"
            app = mAm.startProcessLocked(procName, r.appInfo, true, ...); // ⑥
        }
        ... // 后续处理
    }
    • ​② mAm.getProcessRecordLocked(...):​ 这里 mAm 就是大管家 AMS。AMS 翻看它的居民区登记簿 (mProcessNames 等),查找是否已经有名为 procName、属于微信 (r.appInfo.uid) 的居民区 (ProcessRecord)。
    • ​④ realStartServiceLocked(...):​ 如果居民区存在且运行良好,AMS 就指挥该居民区启动这个服务。故事结束(对于进程创建)。
    • ​⑥ mAm.startProcessLocked(...):​ ​关键!​ 如果居民区不存在,AMS 就需要负责创建它。它会怎么做?
  3. ​管家联系育婴堂 (startProcessLocked -> Zygote):​​ AMS 知道,创建新居民区(进程)这种精细活,得找专业的------育婴堂 (Zygote)!

    arduino 复制代码
    java
    Copy
    // frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
    final ProcessRecord startProcessLocked(String processName, ...) {
        ... // 创建或找到ProcessRecord对象
        // ★ 关键点 ★ ④ 联系育婴堂 (Zygote),孵化新进程!
        Process.ProcessStartResult startResult = Process.start(entryPoint, ...);
        ... // 处理结果,更新登记簿
        return app;
    }
    • AMS 会通过 ​信使系统 (Binder IPC)​ ,向育婴堂 (Zygote) 发送指令:"我需要一个符合 entryPoint (通常是 android.app.ActivityThread) 标准的、名字叫 processName 的、属于微信 (uid) 的新居民区!"。
  4. ​育婴堂孵化新进程 (Zygote):​ ​ Zygote 收到指令,利用它预先加载好的资源和能力,高效地"孵化"出一个新的应用程序进程。这个新进程一出生就运行着 ActivityThread(可以理解为这个居民区的区长)。

  5. ​新居民区报到 (attachApplication):​ ​ 新进程孵化完成后,它的"区长" (ActivityThread) 会通过 ​​信使系统 (Binder IPC)​ ​,向王宫核心的大管家 AMS 报到:"大管家您好!我是新居民区 com.tencent.mm:location 的区长 ActivityThread,我带着我这里的资源信息 (ApplicationThread - 这个区的内部通信接口) 来登记了!"

  6. ​管家登记并安排工作:​ ​ AMS 收到报到信息,在它的居民区登记簿 (mPidsSelfLocked 等) 中更新这个新 ProcessRecord 的信息(尤其是记录下 ApplicationThread,这是 AMS 以后指挥这个居民区工作的关键通道)。然后,AMS 就可以指挥这个新的居民区去执行最初触发它创建的任务了------启动那个微信的位置服务 (realStartServiceLocked)。新居民区正式投入运行!


​第三幕:管家和他的家族 - AMS 家族​

大管家 AMS 深居王宫核心 (SystemServer 进程),普通居民 (App) 是无法直接见到它的。那么居民们怎么请求管家办事(比如启动一个 Activity)呢?这就引出了 AMS 家族的其他成员。

  1. ​居民的需求 (启动 Activity):​​ 微信居民区的居民(比如微信的主界面)想启动一个新的聊天窗口(另一个 Activity)。

  2. ​找前台助手 (Instrumentation.execStartActivity -> ActivityManager):​

    scss 复制代码
    java
    Copy
    // frameworks/base/core/java/android/app/Instrumentation.java
    public ActivityResult execStartActivity(...) {
        ... // 准备请求数据 (Intent, options等)
        // 1. 找管家助手 (ActivityManager)
        int result = ActivityManagerNative.getDefault()
                .startActivity(...); // ★ 关键点 ★ ⑤
        ... // 检查结果
    }
    • ​★ 关键点 ★ ⑤ ActivityManagerNative.getDefault():​ ​ 这是居民接触管家的入口。它返回一个看似是 IActivityManager 接口的东西。让我们看看这个 getDefault() 做了什么:

      csharp 复制代码
      java
      Copy
      // frameworks/base/core/java/android/app/ActivityManagerNative.java
      static public IActivityManager getDefault() {
          return gDefault.get();
      }
      private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
          protected IActivityManager create() {
              // 1. 通过王国服务注册表 (ServiceManager) 查找叫 "activity" 的服务
              IBinder b = ServiceManager.getService("activity"); // ①
              // 2. 把这个服务连接对象 (Binder代理) 包装成我们好用的接口
              IActivityManager am = asInterface(b); // ②
              return am;
          }
      };
      • ​① ServiceManager.getService("activity"):​ ​ 通过王国服务注册中心 (ServiceManager) 查询名为 "activity" 的服务。这个注册中心知道所有重要服务的位置。它返回一个 IBinder 对象,这是 ​​信使系统 (Binder)​​ 的通用通信句柄,指向王宫核心里的真正 AMS。

      • ​② asInterface(b):​ ​ 把这个底层的 IBinder 包装成一个更容易使用的接口对象:

        typescript 复制代码
        java
        Copy
        static public IActivityManager asInterface(IBinder obj) {
            ... // 一些检查
            // ★ 关键点 ★ ⑥ 创建管家助手代理 (ActivityManagerProxy - AMP)
            return new ActivityManagerProxy(obj);
        }
        • 这里创建了 ​管家助手代理 (ActivityManagerProxy - AMP)​ActivityManagerNative.getDefault() 最终返回的就是这个 AMP 对象。​所以,居民接触到的 ActivityManager,实际上是这个 AMP 代理。​
  3. ​助手代理发送请求 (AMP.startActivity):​

    java 复制代码
    java
    Copy
    // frameworks/base/core/java/android/app/ActivityManagerNative.java (内部类)
    class ActivityManagerProxy implements IActivityManager {
        private final IBinder mRemote; // 指向真正AMS的通信句柄
        public ActivityManagerProxy(IBinder remote) {
            mRemote = remote; // 构造函数保存了指向AMS的Binder引用
        }
        public int startActivity(...) throws RemoteException {
            ... // 准备数据包 (Parcel data)
            // ★ 关键点 ★ ⑦ 通过信使系统 (Binder) 发送请求给真正的管家AMS!
            mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);
            ... // 读取回复
            return result;
        }
    }
    • mRemote 就是之前从 ServiceManager 拿到的指向真正 AMS 的 IBinder
    • mRemote.transact(...): 这是 ​信使系统 (Binder IPC)​ 的核心调用。它将请求类型 (START_ACTIVITY_TRANSACTION) 和打包好的请求数据 (data) 发送出去。
  4. ​信使送达王宫,管家接收 (AMN.onTransact -> AMS.startActivity):​ ​ 信使 (Binder 驱动) 将请求送达王宫核心 (SystemServer 进程)。在 AMS 这边,有一个对应的接收端 (ActivityManagerNative - AMN):

    java 复制代码
    java
    Copy
    // frameworks/base/core/java/android/app/ActivityManagerNative.java
    @Override
    public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
        switch (code) {
            case START_ACTIVITY_TRANSACTION: {
                ... // 从data包解析出请求参数
                // ★ 关键点 ★ ⑧ 调用真正大管家AMS的startActivity方法!
                int result = startActivity(...); // 注意:这里的startActivity是抽象方法
                ... // 打包回复
                return true;
            }
            ... // 其他事务
        }
    }
    • ActivityManagerNative (AMN) 是一个 ​抽象类​ 。它接收请求 (onTransact),并根据请求类型 (code) 调用相应的抽象方法 (如 startActivity)。​谁实现了这些抽象方法呢?​
  5. ​真正大管家处理请求 (AMS.startActivity):​ ​ 是的,就是我们的大管家 ActivityManagerService!它是 ActivityManagerNative 的子类,实现了所有抽象方法:

    java 复制代码
    java
    Copy
    // frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
    @Override
    public final int startActivity(...) {
        ... // 权限检查等
        return startActivityAsUser(...); // 通常会调用这个
    }
    @Override
    public final int startActivityAsUser(...) {
        ... // 用户处理等
        // ★ 关键点 ★ ⑨ AMS开始处理启动Activity的核心逻辑!
        return mActivityStarter.startActivityMayWait(...);
    }
    • ​⑨ mActivityStarter.startActivityMayWait(...):​ 这才是启动 Activity 庞大流程的真正起点!AMS 会检查权限、查找目标 Activity、检查目标进程是否存在(不存在则像第二幕那样创建)、处理启动模式、管理任务栈 (Task) 等等。这个流程非常复杂,最终目标是把新的聊天窗口显示出来。

​AMS 家族关系图:​

  1. ActivityManager (App可见):​ 居民接触的前台。它通过 ActivityManagerNative.getDefault() 拿到...
  2. ActivityManagerProxy (AMP - 代理):​ 助手代理。持有底层 IBinder (指向 AMS)。居民调用它的方法,它通过 Binder transact 将请求发送给...
  3. ActivityManagerNative (AMN - 基类):​ 位于 AMS 端。接收 Binder 请求 (onTransact),调用对应的抽象方法 (如 startActivity)。
  4. ActivityManagerService (AMS - 实现):​ 真正的王国大管家!继承自 AMN,实现了所有抽象方法。处理核心逻辑(进程管理、组件启动、调度等)。它与系统其他部分(如 ActivityStarter, ProcessRecord, WindowManagerService 等)紧密协作。

​总结一下这个家族:​

  • ActivityManager + AMP:​ 这是​客户端 (App)​ 使用的接口和代理。它们让 App 感觉像是在调用一个本地对象,实际是通过 Binder IPC 跨进程通信。
  • AMN + AMS:​ 这是​服务端 (SystemServer)​ 的实现。AMN 处理底层 Binder 通信的解包,AMS 是真正干活的核心服务。
  • Binder IPC:​ 是连接客户端和服务端、让它们跨进程协作的通信管道。

​故事终:王国的运转​

至此,我们的大管家 AMS 完成了它的就职典礼(启动),掌握了指挥居民区建设(进程启动)的能力,并通过它的家族成员(ActivityManager/AMP/AMN/Binder)为王国里的所有居民(App)提供了管理服务的入口。它日复一日地协调着四大组件(Activity, Service, BroadcastReceiver, ContentProvider)的生命周期,管理着应用程序进程的生老病死,调度着系统资源,确保安卓王国这个庞大而复杂的生态系统能够有序、高效地运行。每一次应用的启动、每一次页面的切换、每一次服务的运行,背后都有这位大管家和它庞大的家族在默默工作。

相关推荐
fatiaozhang952744 分钟前
中兴B860AV1.1强力降级固件包
android·adb·电视盒子·av1·机顶盒rom·魔百盒刷机
橙子199110162 小时前
Kotlin 中的 Object
android·开发语言·kotlin
AD钙奶-lalala6 小时前
android:foregroundServiceType详解
android
大胃粥9 小时前
Android V app 冷启动(13) 焦点窗口更新
android
fatiaozhang952713 小时前
中兴B860AV1.1_晨星MSO9280芯片_4G和8G闪存_TTL-BIN包刷机固件包
android·linux·adb·电视盒子·av1·魔百盒刷机
fatiaozhang952714 小时前
中兴B860AV1.1_MSO9280_降级后开ADB-免刷机破解教程(非刷机)
android·adb·电视盒子·av1·魔百盒刷机·移动魔百盒·魔百盒固件
二流小码农14 小时前
鸿蒙开发:绘制服务卡片
android·ios·harmonyos
微信公众号:AI创造财富14 小时前
adb 查看android 设备的硬盘及存储空间
android·adb
码农果果15 小时前
Google 提供的一组集成测试套件----XTS
android