外观
ServiceManager、Binder 和 getSystemService 是什么关系?
标准回答
ServiceManager 可以理解为系统 Binder 服务的登记处。服务端把名称与 Binder 接口注册进去,客户端按名称查到接口后,就可以通过 Binder 与目标服务通信。它主要解决“去哪里找到这个服务”。
Binder 是通信机制,AIDL 可以用来定义接口并生成代理代码。ServiceManager 不是每次业务调用的中转站:客户端取得并持有目标接口后,后续调用通常直接指向对应服务端,不必让登记处代为执行所有业务。
应用里常用 getSystemService 获取 ActivityManager、DisplayManager 等客户端管理对象。这些对象把缓存、参数处理和系统通信封装起来,但不能理解成每次调用 getSystemService 都创建一个系统服务进程,也不能假设每个 Manager 方法都立即发起 IPC。普通应用应使用支持的公开 API,隐藏的 ServiceManager 接口不等于可随意调用的 SDK。
还要区分 SystemServiceManager:它主要在 system_server 中管理系统服务的启动和生命周期阶段,与登记 Binder 名称的 ServiceManager 职责不同。名字相似,但一个偏启动管理,一个偏服务发现。
关键机制
- 注册和查找:ServiceManager;跨进程调用:Binder;接口契约:AIDL。
- 客户端 Manager 是应用调用入口,不是远程服务本体。
- 服务发现成功后仍需权限校验,也仍可能遇到服务死亡或调用超时。
通俗例子
获取 DisplayManager 后查询显示设备,拿到的是系统能力的客户端封装,不是把 DisplayManagerService 创建到了自己的进程里。结果可能来自缓存或通过系统通信取得,取决于具体方法实现。
追问与回答
系统服务和我写的 Service 有什么区别?
应用里的 Service 是四大组件之一,有 Manifest 声明和 onCreate、onStartCommand、onBind 等组件生命周期。系统服务是对系统能力实现的统称,AMS、WMS 这类服务通常不是通过应用的 startService 来启动,也不沿用这套应用组件生命周期。两者都可能暴露 Binder,但组织和启动方式不同。
拿到了 Binder,是否就能调用所有方法?
不能。取得接口只是找到了通信目标,服务端仍可以检查调用 UID、权限、参数和用户范围;SELinux 等规则也可能约束访问。调用过程中还可能遇到进程死亡或其他错误。因此服务发现、访问授权和业务成功是三件不同的事。
易混淆点
应用自己写的四大组件 Service,不是默认都注册到全局 ServiceManager。bindService 通常通过组件管理链路得到应用提供的 Binder。
参考资料
内容来源
- Android 技术札记 · 原条目
framework-servicemanager