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
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
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
@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 两张表
| 方法 | 注册表 | 消费者 | 跨进程 |
|---|---|---|---|
| publishBinderService | ServiceManager | ServiceManager.getService | 是 |
| publishLocalService | LocalServices | getLocalService | 否 |
3. 发布实现
3.1 Binder发布
源码文件:frameworks/base/services/core/java/com/android/server/SystemService.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发布
protected final <T> void publishLocalService(
Class<T> type, T service) {
LocalServices.addService(type, service);
}LocalServices 使用 Java class 作为 key,不创建 BinderProxy,不经过驱动。类内调用成功而外部查询失败时,应先确认是否只发布了 LocalService。
3.3 读取路径
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
@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
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.javaframeworks/base/services/tests/servicestests/src/com/android/server/SystemServiceManagerTest.java
测试覆盖服务状态、实例启动、重复类名和 boot phase 顺序;不把完整 system_server、真实驱动和设备 ServiceManager 启动合并成单元测试。
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 依赖。
