要理解 App 端获取 AMS(ActivityManagerService)客户端代理的流程,需先明确核心背景:AMS 是 Android 系统中最核心的系统服务之一,运行在system_server进程,负责 Activity 管理、进程调度等核心功能。由于 App 运行在独立的应用进程,必须通过Binder 跨进程通信(IPC) 与 AMS 交互,而 App 拿到的 “AMS 客户端代理” 本质是IActivityManager接口的实现类(由 AIDL 编译器生成),用于封装 Binder 通信逻辑。
一、核心原理铺垫
在分析流程前,先明确 3 个关键概念:
- AIDL 接口(IActivityManager) :定义 AMS 客户端与服务端的通信协议,编译后生成
IActivityManager.Stub(服务端抽象类,AMS 需继承实现)和IActivityManager.Stub.Proxy(客户端代理类,App 实际持有)。 - ServiceManager:系统服务的 “注册表”,运行在
system_server进程,管理所有已注册的系统服务(如 AMS、PMS),App 通过它获取目标服务的 Binder 引用。 - SystemServiceRegistry:Android 框架层的 “系统服务分发中心”,在应用进程启动时预注册所有系统服务的 “获取逻辑”(如
ACTIVITY_SERVICE对应如何获取 AMS 代理),避免硬编码耦合。
二、App 获取 AMS 客户端代理的详细流程
以下流程基于 Android 10(API 29)源码,核心逻辑在各 Android 版本中保持一致,仅细节有微调。流程分为6 个关键步骤,每个步骤结合源码解析:
步骤 1:App 调用Context.getSystemService(ACTIVITY_SERVICE)
App 获取 AMS 代理的入口是Context的getSystemService方法,通常在 Activity/Application 中调用:
// App代码示例:获取AMS客户端代理
ActivityManager ams = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
Context是抽象类,其实际实现类是ContextImpl(每个 App 进程会初始化一个ContextImpl实例),因此该方法的具体逻辑在ContextImpl中:
// ContextImpl.java(frameworks/base/core/java/android/app/ContextImpl.java)
@Override
public Object getSystemService(String name) {
// 委托给SystemServiceRegistry处理服务获取
return SystemServiceRegistry.getSystemService(this, name);
}
步骤 2:SystemServiceRegistry根据服务名匹配 “服务获取器”
SystemServiceRegistry是框架层的 “系统服务注册中心”,在类加载时(应用进程启动阶段)通过静态代码块预注册所有系统服务,包括ACTIVITY_SERVICE对应的获取逻辑。
关键源码:SystemServiceRegistry的静态注册
// SystemServiceRegistry.java(frameworks/base/core/java/android/app/SystemServiceRegistry.java)
static {
// 注册ACTIVITY_SERVICE:服务名 -> 服务获取器(ServiceFetcher)
registerService(Context.ACTIVITY_SERVICE, ActivityManager.class,
new CachedServiceFetcher<ActivityManager>() {
@Override
public ActivityManager createService(ContextImpl ctx) {
// 核心:通过ActivityManager.getService()获取代理
return ActivityManager.getService();
}
});
// 同时注册其他服务(如PMS、WMS等)
// registerService(Context.POWER_SERVICE, PowerManager.class, ...)
// ...
}
// 对外提供的服务获取入口
public static Object getSystemService(ContextImpl ctx, String name) {
// 根据服务名获取预注册的ServiceFetcher
ServiceFetcher<?> fetcher = SYSTEM_SERVICE_FETCHERS.get(name);
if (fetcher == null) {
return null;
}
// 调用ServiceFetcher获取服务实例(含缓存逻辑)
return fetcher.getService(ctx);
}
这里的CachedServiceFetcher是ServiceFetcher的子类,核心作用是缓存服务代理(避免每次获取都重新创建),其getService方法会先检查缓存,无缓存则调用createService创建。
步骤 3:ServiceFetcher调用ActivityManager.getService()
CachedServiceFetcher的createService方法直接委托给ActivityManager.getService(),这是获取 AMS 代理的 “桥梁方法”。
关键源码:ActivityManager.getService()
// ActivityManager.java(frameworks/base/core/java/android/app/ActivityManager.java)
public static IActivityManager getService() {
// 单例模式:缓存IActivityManager代理实例
return IActivityManagerSingleton.get();
}
// 静态单例,负责创建和缓存IActivityManager代理
private static final Singleton<IActivityManager> IActivityManagerSingleton =
new Singleton<IActivityManager>() {
@Override
protected IActivityManager create() {
// 1. 通过ServiceManager获取AMS的Binder引用(IBinder对象)
final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
// 2. 将IBinder转换为IActivityManager客户端代理
final IActivityManager am = IActivityManager.Stub.asInterface(b);
return am;
}
};
这里的Singleton是 Android 框架的单例工具类,确保IActivityManager代理实例在应用进程中唯一。
步骤 4:ServiceManager.getService()获取 AMS 的 Binder 引用
ServiceManager是系统服务的 “注册表”,运行在system_server进程。ServiceManager.getService(String name)的作用是:跨进程查询name对应的系统服务(此处为 AMS)的 Binder 对象。
关键细节:
ServiceManager本身也是一个 Binder 服务(IServiceManager),App 通过ServiceManager的代理与其实例通信。ServiceManager.getService("activity")返回的IBinder对象,是 AMS 在应用进程中的 “Binder 句柄”(可理解为跨进程通信的 “地址”)。
源码简化(ServiceManager.java):
// ServiceManager.java(frameworks/base/core/java/android/os/ServiceManager.java)
public static IBinder getService(String name) {
try {
// 调用IServiceManager的getService方法(跨进程)
IBinder service = sServiceManager.getService(name);
return service;
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
// sServiceManager是IServiceManager的客户端代理(初始化时获取)
private static IServiceManager sServiceManager;
static {
// 连接ServiceManager,获取其代理
sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());
}
步骤 5:IActivityManager.Stub.asInterface()转换为客户端代理
ServiceManager返回的IBinder是 “原始” 的 Binder 句柄,无法直接调用 AMS 的方法。需通过IActivityManager.Stub.asInterface(IBinder)将其转换为IActivityManager接口的实现类 ——客户端代理(Proxy) 。
该方法由 AIDL 编译器自动生成(生成文件路径:out/soong/.intermediates/frameworks/base/core/java/android/app/IActivityManager.java),核心逻辑如下:
// IActivityManager.java(AIDL生成)
public interface IActivityManager extends IInterface {
// 服务端抽象类(AMS需继承实现)
public static abstract class Stub extends Binder implements IActivityManager {
// 将IBinder转换为IActivityManager代理
public static IActivityManager asInterface(IBinder obj) {
if (obj == null) {
return null;
}
// 1. 若在同一进程(极少情况,如system_server内部调用),直接返回服务端实例
IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (iin != null && iin instanceof IActivityManager) {
return (IActivityManager) iin;
}
// 2. 跨进程:返回Proxy代理类(封装Binder通信)
return new Proxy(obj);
}
// 客户端代理类(App实际持有)
private static class Proxy implements IActivityManager {
private IBinder mRemote; // 步骤4获取的AMS Binder引用
Proxy(IBinder remote) {
mRemote = remote;
}
// 示例:调用AMS的startActivity方法(通过Binder发送请求)
@Override
public int startActivity(...) throws RemoteException {
// 封装参数为Parcel
Parcel _data = Parcel.obtain();
Parcel _reply = Parcel.obtain();
int _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
// 写入startActivity的参数(如Intent、ActivityInfo等)
// ...
// 发送Binder请求到服务端(AMS),阻塞等待响应
mRemote.transact(Stub.TRANSACTION_startActivity, _data, _reply, 0);
_reply.readException();
_result = _reply.readInt();
} finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
// 其他AMS方法(如finishActivity、bindService等)的代理实现...
}
}
// AMS的核心方法定义(如startActivity、getRunningTasks等)
int startActivity(...) throws RemoteException;
// ...
}
步骤 6:缓存代理并返回给 App
ActivityManager.getService()通过Singleton缓存IActivityManager代理实例后,将其返回给ServiceFetcher,ServiceFetcher再将其向上传递给ContextImpl,最终返回给 App。
App 拿到的ActivityManager实例,其内部持有IActivityManager代理,所有对ActivityManager的操作(如getRunningAppProcesses())都会委托给该代理,通过 Binder 跨进程调用 AMS 的服务端实现。
三、时序图(Mermaid 语法)
以下时序图清晰展示了各参与者(进程 / 类)的交互顺序,标注了关键跨进程通信(IPC)节点:
AMSProxyIActivityManager.StubServiceManagerActivityManagerServiceFetcherSystemServiceRegistryContextImplAppAMS(system_server进程)ServiceManager(system_server进程)ActivityManager(App进程)ServiceFetcher(App进程)SystemServiceRegistry(App进程)ContextImpl(App进程)App(应用进程)AMSProxyIActivityManager.StubServiceManagerActivityManagerServiceFetcherSystemServiceRegistryContextImplAppAMS(system_server进程)ServiceManager(system_server进程)ActivityManager(App进程)ServiceFetcher(App进程)SystemServiceRegistry(App进程)ContextImpl(App进程)App(应用进程)getSystemService(ACTIVITY_SERVICE)getSystemService(ContextImpl, "activity")getService(ContextImpl)检查缓存(无则创建)getService()检查Singleton缓存(无则创建)getService("activity")(IPC)查询AMS的Binder引用返回IBinder(AMS句柄)asInterface(IBinder)返回Proxy(客户端代理)返回Proxy缓存Proxy返回Proxy返回Proxy返回ActivityManager(持有Proxy)调用方法(如startActivity)发送Binder请求(IPC)返回处理结果返回结果
四、关键节点补充说明
-
缓存机制:
ActivityManager通过Singleton缓存IActivityManager代理,确保应用进程中唯一。SystemServiceRegistry的CachedServiceFetcher也会缓存ActivityManager实例,避免重复创建。
-
跨进程通信边界:
- 仅
ServiceManager.getService()和Proxy调用mRemote.transact()是跨进程操作(从 App 进程到system_server进程),其他步骤均在 App 进程内执行。
- 仅
-
权限控制:
- App 获取 AMS 代理本身无需特殊权限,但调用代理的敏感方法(如
forceStopPackage())时,AMS 会在服务端检查权限(如android.permission.FORCE_STOP_PACKAGES),无权限则抛出SecurityException。
- App 获取 AMS 代理本身无需特殊权限,但调用代理的敏感方法(如
-
版本差异:
- Android O(8.0,API 26)后,
ServiceManager的部分接口被隐藏(如getService),但框架层仍通过内部 API 调用,对 App 层流程无影响。 - Android 12(API 31)后,
IActivityManager的部分方法被迁移到ActivityTaskManagerService(ATMS),但 “获取代理” 的核心流程不变。
- Android O(8.0,API 26)后,
总结
App 获取 AMS 客户端代理的本质是 “通过系统服务注册中心找到获取逻辑,再通过 Binder 跨进程获取服务端句柄,最后转换为封装通信逻辑的代理类”。整个流程由 Android 框架层高度封装,App 无需关注 Binder 通信细节,只需通过getSystemService即可便捷地与 AMS 交互,体现了 Android 系统架构的解耦与易用性。