理解App 端获取 AMS(ActivityManagerService)客户端代理的流程

79 阅读7分钟

要理解 App 端获取 AMS(ActivityManagerService)客户端代理的流程,需先明确核心背景:AMS 是 Android 系统中最核心的系统服务之一,运行在system_server进程,负责 Activity 管理、进程调度等核心功能。由于 App 运行在独立的应用进程,必须通过Binder 跨进程通信(IPC)  与 AMS 交互,而 App 拿到的 “AMS 客户端代理” 本质是IActivityManager接口的实现类(由 AIDL 编译器生成),用于封装 Binder 通信逻辑。

一、核心原理铺垫

在分析流程前,先明确 3 个关键概念:

  1. AIDL 接口(IActivityManager) :定义 AMS 客户端与服务端的通信协议,编译后生成IActivityManager.Stub(服务端抽象类,AMS 需继承实现)和IActivityManager.Stub.Proxy(客户端代理类,App 实际持有)。
  2. ServiceManager:系统服务的 “注册表”,运行在system_server进程,管理所有已注册的系统服务(如 AMS、PMS),App 通过它获取目标服务的 Binder 引用。
  3. SystemServiceRegistry:Android 框架层的 “系统服务分发中心”,在应用进程启动时预注册所有系统服务的 “获取逻辑”(如ACTIVITY_SERVICE对应如何获取 AMS 代理),避免硬编码耦合。

二、App 获取 AMS 客户端代理的详细流程

以下流程基于 Android 10(API 29)源码,核心逻辑在各 Android 版本中保持一致,仅细节有微调。流程分为6 个关键步骤,每个步骤结合源码解析:

步骤 1:App 调用Context.getSystemService(ACTIVITY_SERVICE)

App 获取 AMS 代理的入口是ContextgetSystemService方法,通常在 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);
}

这里的CachedServiceFetcherServiceFetcher的子类,核心作用是缓存服务代理(避免每次获取都重新创建),其getService方法会先检查缓存,无缓存则调用createService创建。

步骤 3:ServiceFetcher调用ActivityManager.getService()

CachedServiceFetchercreateService方法直接委托给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代理实例后,将其返回给ServiceFetcherServiceFetcher再将其向上传递给ContextImpl,最终返回给 App。

App 拿到的ActivityManager实例,其内部持有IActivityManager代理,所有对ActivityManager的操作(如getRunningAppProcesses())都会委托给该代理,通过 Binder 跨进程调用 AMS 的服务端实现。

三、时序图(Mermaid 语法)

以下时序图清晰展示了各参与者(进程 / 类)的交互顺序,标注了关键跨进程通信(IPC)节点:

appGetAMSProxy.png

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)返回处理结果返回结果

四、关键节点补充说明

  1. 缓存机制

    • ActivityManager通过Singleton缓存IActivityManager代理,确保应用进程中唯一。
    • SystemServiceRegistryCachedServiceFetcher也会缓存ActivityManager实例,避免重复创建。
  2. 跨进程通信边界

    • ServiceManager.getService()Proxy调用mRemote.transact()是跨进程操作(从 App 进程到system_server进程),其他步骤均在 App 进程内执行。
  3. 权限控制

    • App 获取 AMS 代理本身无需特殊权限,但调用代理的敏感方法(如forceStopPackage())时,AMS 会在服务端检查权限(如android.permission.FORCE_STOP_PACKAGES),无权限则抛出SecurityException
  4. 版本差异

    • Android O(8.0,API 26)后,ServiceManager的部分接口被隐藏(如getService),但框架层仍通过内部 API 调用,对 App 层流程无影响。
    • Android 12(API 31)后,IActivityManager的部分方法被迁移到ActivityTaskManagerService(ATMS),但 “获取代理” 的核心流程不变。

总结

App 获取 AMS 客户端代理的本质是 “通过系统服务注册中心找到获取逻辑,再通过 Binder 跨进程获取服务端句柄,最后转换为封装通信逻辑的代理类”。整个流程由 Android 框架层高度封装,App 无需关注 Binder 通信细节,只需通过getSystemService即可便捷地与 AMS 交互,体现了 Android 系统架构的解耦与易用性。