我们把这篇关于 Android 核心大管家 ActivityManagerService
(AMS) 启动和运作的文章,变成一个发生在「安卓王国」里的故事,结合代码,让它更容易理解。
故事梗概: 想象一个庞大的安卓王国(你的手机)。这个王国需要一个超级大管家(AMS)来管理所有居民(App)、协调资源、确保一切有序运行。这个故事讲的就是这个大管家如何被任命上岗(启动),以及它如何指挥居民区的建立(进程启动)和家族成员如何分工协作的。
核心角色:
- 国王 (Linux Kernel): 最底层的统治者,负责土地、资源分配(硬件)。
- 王宫总管 (init 进程): 国王的第一个臣子,负责启动其他重要官员。
- 育婴堂负责人 (Zygote 进程): 负责按需"孕育"出新的居民区(App 进程)。
- 王宫核心 (SystemServer 进程): 国王最重要的行政中心,里面住着各种关键大臣(系统服务)。
- 大管家 - AMS (ActivityManagerService): 我们的主角,住在王宫核心里,管理王国居民。
- 大管家助手 (ActivityManager): 普通居民(App)接触到的"前台",它负责把居民的请求转告给真正的、住在王宫深处的大管家(AMS)。
- 信使系统 (Binder IPC): 王国里的高效通信网络,用于王宫内部以及王宫与居民区之间的消息传递。
第一幕:王宫启动,任命大管家 (AMS 启动流程)
-
国王登基 (Bootloader -> Kernel): 手机开机,硬件通电,国王(Linux Kernel)掌握大权。
-
任命总管 (init 进程): 国王任命了第一位大臣------王宫总管(
init
进程)。 -
总管启动核心 (init -> Zygote / SystemServer): 总管根据王国的宪法(
init.rc
脚本),启动了两个极其重要的机构:- 育婴堂 (Zygote 进程): 稍后再讲它的作用。
- 王宫核心 (SystemServer 进程): 这是王国真正的行政心脏,所有核心系统服务都在这里运行。我们的故事重点发生在这里。
-
王宫核心开张 (
SystemServer.main()
):scssjava 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 就在这里被任命!
- ①
-
任命大管家 AMS (
startBootstrapServices()
):csharpjava 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 怎么做的呢?它有一套标准流程:kotlinjava 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; // 把新大臣返回给调用者 }
-
当
serviceClass
是ActivityManagerService.Lifecycle.class
时:-
②
constructor.newInstance(mContext)
: 这会调用Lifecycle
的构造函数:scalajava 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
),并赋值给SystemServer
的mActivityManagerService
变量。至此,王宫核心 (SystemServer
) 拥有了它的大管家 (AMS) 的引用。
-
-
-
大管家就位: AMS 在
SystemServer
进程中创建、初始化、启动完成。它现在知道王国里有哪些资源,知道服务大臣总管 (SSM),也知道育婴堂 (Zygote) 的位置(稍后用到)。它准备好接收命令,管理王国了!
第二幕:居民区的建立 - AMS 与进程启动
大管家 AMS 上岗后,它的核心职责之一就是:当有新的居民(App)想住进王国,或者已有的居民需要更多空间(启动新组件)时,确保这些居民有地方住(有进程运行)。
-
居民申请入住 (启动 Service): 想象一个居民(比如微信)想启动一个后台服务(比如位置服务)。微信自己已经有一个居民区(主进程),但它可能需要为这个服务单独开辟一个区域(新进程,如果服务声明了
android:process
)。 -
管家检查 (
bringUpServiceLocked
): 王国负责管理服务的部门 (ActiveServices
) 收到申请。它会请示大管家 AMS:typescriptjava 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 就需要负责创建它。它会怎么做?
- ②
-
管家联系育婴堂 (
startProcessLocked
-> Zygote): AMS 知道,创建新居民区(进程)这种精细活,得找专业的------育婴堂 (Zygote)!arduinojava 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
) 的新居民区!"。
- AMS 会通过 信使系统 (Binder IPC) ,向育婴堂 (Zygote) 发送指令:"我需要一个符合
-
育婴堂孵化新进程 (Zygote): Zygote 收到指令,利用它预先加载好的资源和能力,高效地"孵化"出一个新的应用程序进程。这个新进程一出生就运行着
ActivityThread
(可以理解为这个居民区的区长)。 -
新居民区报到 (attachApplication): 新进程孵化完成后,它的"区长" (
ActivityThread
) 会通过 信使系统 (Binder IPC) ,向王宫核心的大管家 AMS 报到:"大管家您好!我是新居民区com.tencent.mm:location
的区长ActivityThread
,我带着我这里的资源信息 (ApplicationThread
- 这个区的内部通信接口) 来登记了!" -
管家登记并安排工作: AMS 收到报到信息,在它的居民区登记簿 (
mPidsSelfLocked
等) 中更新这个新ProcessRecord
的信息(尤其是记录下ApplicationThread
,这是 AMS 以后指挥这个居民区工作的关键通道)。然后,AMS 就可以指挥这个新的居民区去执行最初触发它创建的任务了------启动那个微信的位置服务 (realStartServiceLocked
)。新居民区正式投入运行!
第三幕:管家和他的家族 - AMS 家族
大管家 AMS 深居王宫核心 (SystemServer
进程),普通居民 (App) 是无法直接见到它的。那么居民们怎么请求管家办事(比如启动一个 Activity)呢?这就引出了 AMS 家族的其他成员。
-
居民的需求 (启动 Activity): 微信居民区的居民(比如微信的主界面)想启动一个新的聊天窗口(另一个 Activity)。
-
找前台助手 (
Instrumentation.execStartActivity
->ActivityManager
):scssjava 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()
做了什么:csharpjava 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
包装成一个更容易使用的接口对象:typescriptjava Copy static public IActivityManager asInterface(IBinder obj) { ... // 一些检查 // ★ 关键点 ★ ⑥ 创建管家助手代理 (ActivityManagerProxy - AMP) return new ActivityManagerProxy(obj); }
- 这里创建了 管家助手代理 (ActivityManagerProxy - AMP) !
ActivityManagerNative.getDefault()
最终返回的就是这个AMP
对象。所以,居民接触到的ActivityManager
,实际上是这个AMP
代理。
- 这里创建了 管家助手代理 (ActivityManagerProxy - AMP) !
-
-
-
助手代理发送请求 (
AMP.startActivity
):javajava 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
) 发送出去。
-
信使送达王宫,管家接收 (
AMN.onTransact
->AMS.startActivity
): 信使 (Binder
驱动) 将请求送达王宫核心 (SystemServer
进程)。在 AMS 这边,有一个对应的接收端 (ActivityManagerNative
- AMN):javajava 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
)。谁实现了这些抽象方法呢?
-
真正大管家处理请求 (
AMS.startActivity
): 是的,就是我们的大管家ActivityManagerService
!它是ActivityManagerNative
的子类,实现了所有抽象方法:javajava 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 家族关系图:
-
ActivityManager
(App可见): 居民接触的前台。它通过ActivityManagerNative.getDefault()
拿到... -
ActivityManagerProxy
(AMP - 代理): 助手代理。持有底层IBinder
(指向 AMS)。居民调用它的方法,它通过 Bindertransact
将请求发送给... -
ActivityManagerNative
(AMN - 基类): 位于 AMS 端。接收 Binder 请求 (onTransact
),调用对应的抽象方法 (如startActivity
)。 -
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)的生命周期,管理着应用程序进程的生老病死,调度着系统资源,确保安卓王国这个庞大而复杂的生态系统能够有序、高效地运行。每一次应用的启动、每一次页面的切换、每一次服务的运行,背后都有这位大管家和它庞大的家族在默默工作。