Skip to content

SystemService中的Binder

以 BatteryService 为例,追踪 SystemService 生命周期、publishBinderService、ServiceManager 和 LocalServices。

基于android-17.0.0_r1
AndroidBinderSystemServerSystemServiceJava框架源码阅读

SystemService中的Binder ​

SystemService 的 Binder 发布分为两条状态线:publishBinderService() 进入 ServiceManager,publishLocalService() 进入 LocalServices。前者可被其他进程查询,后者只在 system_server 进程内查找。

本文面向已经读过 Java-IBinder接口、Binder基类详解 和 getService查询服务 的读者。本文用 Android 17 的 BatteryService 追踪构造、onStart、Binder 注册、LocalServices 注册和 boot phase;不重复 SystemServiceManager 的全部启动编排。

1. 生命周期 ​

1.1 SystemService ​

源码文件:frameworks/base/services/core/java/com/android/server/SystemService.java

java
public abstract void onStart();
public void onBootPhase(@BootPhase int phase) {}

构造函数初始化服务;onStart() 让服务运行并发布 Binder;随后 SystemServiceManager 调用多个 onBootPhase()。生命周期方法由 system_server 主线程调用,部分 boot phase 可按配置并行。

1.2 启动实例 ​

源码文件:frameworks/base/services/core/java/com/android/server/SystemServiceManager.java

java
public void startService(@NonNull SystemService service) {
    String className = service.getClass().getName();
    if (mServiceClassnames.contains(className)) return;
    mServiceClassnames.add(className);
    mServices.add(service);
    service.onStart();
}

重复类名直接跳过;构造或 onStart() 抛异常则服务不会形成完整发布状态。

2. BatteryService ​

2.1 发布入口 ​

源码文件:frameworks/base/services/core/java/com/android/server/BatteryService.java

java
@Override
public void onStart() {
    registerHealthCallback();
    mBinderService = new BinderService();
    publishBinderService("battery", mBinderService);
    mBatteryPropertiesRegistrar =
            new BatteryPropertiesRegistrar();
    publishBinderService("batteryproperties",
                         mBatteryPropertiesRegistrar);
    publishLocalService(BatteryManagerInternal.class,
                        new LocalService());
}

同一 onStart() 注册两个跨进程名称和一个进程内接口。Binder service owner 是 Stub 对象,BatteryService 本身只是生命周期 owner。

2.2 两张表 ​

方法注册表消费者跨进程
publishBinderServiceServiceManagerServiceManager.getService是
publishLocalServiceLocalServicesgetLocalService否

3. 发布实现 ​

3.1 Binder发布 ​

源码文件:frameworks/base/services/core/java/com/android/server/SystemService.java

java
protected final void publishBinderService(String name,
        IBinder service, boolean allowIsolated,
        int dumpPriority) {
    ServiceManager.addService(name, service,
                              allowIsolated, dumpPriority);
}

重载默认禁止 isolated caller 和默认 dump priority;名称、权限、VINTF 和死亡通知由 ServiceManager 后端处理。该方法返回并不等于服务端校验一定成功。

3.2 Local发布 ​

java
protected final <T> void publishLocalService(
        Class<T> type, T service) {
    LocalServices.addService(type, service);
}

LocalServices 使用 Java class 作为 key,不创建 BinderProxy,不经过驱动。类内调用成功而外部查询失败时,应先确认是否只发布了 LocalService。

3.3 读取路径 ​

java
protected final IBinder getBinderService(String name) {
    return ServiceManager.getService(name);
}
protected final <T> T getLocalService(Class<T> type) {
    return LocalServices.getService(type);
}

两个 getter 的 owner 与失败语义不同:Binder 查询可能返回 null/RemoteException,LocalServices 查找只发生在同一 JVM。

4. Boot phase ​

源码文件:frameworks/base/services/core/java/com/android/server/BatteryService.java

java
@Override
public void onBootPhase(int phase) {
    if (phase == PHASE_ACTIVITY_MANAGER_READY) {
        synchronized (mLock) {
            // safe to display shutdown dialog
        }
    }
}

Binder 在 onStart() 发布后即可被查询;boot phase 负责依赖准备和策略工作。消费者可能在后续 phase 完成前进入 Binder 方法,Stub 必须处理未完成状态。

5. 编排边界 ​

源码文件:frameworks/base/services/java/com/android/server/SystemServer.java

java
startBootstrapServices(t);
startCoreServices(t);
startOtherServices(t);
startApexServices(t);

SystemServer 分组决定服务启动相对顺序;ServiceManager 不会自动发现 SystemService 类。BatteryService 位于 core services 启动分组,发布时机由这一编排决定。

6. 失败路径 ​

构造失败或 onStart() 异常时不会完成发布。BatteryService 示例没有显式检查 publishBinderService() 的返回值,因此查询失败需要结合 ServiceManager 日志和服务名检查。线程/依赖问题可能在 Binder 已发布后才于 boot phase 暴露。

7. 测试边界 ​

  • frameworks/base/services/tests/servicestests/src/com/android/server/BatteryServiceTest.java
  • frameworks/base/services/tests/servicestests/src/com/android/server/SystemServiceManagerTest.java

测试覆盖服务状态、实例启动、重复类名和 boot phase 顺序;不把完整 system_server、真实驱动和设备 ServiceManager 启动合并成单元测试。

bash
rg -n "publishBinderService|publishLocalService|getBinderService|getLocalService" \
  frameworks/base/services/core/java/com/android/server/SystemService.java
rg -n "publishBinderService|publishLocalService|onBootPhase" \
  frameworks/base/services/core/java/com/android/server/BatteryService.java
rg -n "startService|startBootPhase|onStart|onBootPhase" \
  frameworks/base/services/core/java/com/android/server/SystemServiceManager.java

排查 system_server 服务外部查不到时,先区分 LocalServices 与 ServiceManager,再检查 onStart()、发布名、addService 错误和 boot phase 依赖。