3. Android系统服务基础
Android 的系统能力大多不是由应用进程直接实现的,而是由运行在 system_server 等系统进程中的系统服务统一提供。应用通过 Context.getSystemService() 拿到一个代理对象,再借助 Binder 机制跨进程调用真正的服务实现。理解这条链路,是后续学习权限校验、系统服务定制与集成的前提。
一、系统服务架构:三层协作
从整体看,Android 系统服务架构可以拆成三层:
- 服务实现层:真正的功能代码,如
ActivityManagerService、PackageManagerService、WindowManagerService,运行在 system_server 进程中。 - Binder 通信层:由
IBinder、Binder、BinderProxy以及 AIDL 生成的Stub/Proxy组成,负责跨进程方法调用与数据序列化。 - 客户端访问层:应用通过
Context、ServiceManager或getSystemService()获取代理,以本地方法的形式调用远程服务。
系统启动时,ServiceManager 作为 Binder 的“总管家”先启动,随后各系统服务向它注册自己,客户端再按名称查询。这个“注册—查询—调用”的模型,是 Android 系统服务能够被应用发现和使用的关键。
二、Context.getSystemService:应用的入口
Context 是应用访问系统服务的统一入口。常见用法如下:
// 获取 ActivityManager 代理
ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
// 获取 PackageManager
PackageManager pm = getPackageManager();
// 获取 WindowManager
WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
// 获取 NotificationManager
NotificationManager nm = getSystemService(NotificationManager.class);
不同服务对应不同的常量名,例如 Context.ACTIVITY_SERVICE、Context.PACKAGE_SERVICE、Context.WINDOW_SERVICE。Android 6.0 之后还支持按 Class 获取,减少强制类型转换。需要注意的是,getSystemService() 返回的通常是代理对象,而不是服务本体;真正的服务运行在 system_server 中。
Context.getSystemService() 获取。部分底层服务需要借助 ServiceManager.getService() 或隐藏 API 访问,普通应用应优先使用公开接口。
三、Binder 机制:跨进程调用的核心
Binder 是 Android 特有的 IPC 机制,相比传统 Socket 或管道,它具备一次拷贝、面向对象、支持引用计数和权限校验等优势。一次典型的 Binder 调用包含以下步骤:
- 客户端调用代理对象的某个方法,例如
am.startActivity()。 - 代理将参数写入
Parcel,调用transact()发起请求。 - Binder 驱动将请求转发到服务端线程池。
- 服务端
onTransact()被调用,解析参数并执行真正逻辑。 - 结果写回
Parcel,沿原路返回客户端。
在 AIDL 中,Stub 是服务端基类,Proxy 是客户端代理。二者共同保证跨进程调用像本地调用一样自然。Binder 还通过 uid/pid 识别调用方身份,为权限校验提供依据。
四、系统服务与应用的交互方式
应用与系统服务的交互并不只有“直接调用”一种,常见方式包括:
| 交互方式 | 典型场景 | 特点 |
|---|---|---|
| 直接 Binder 调用 | ActivityManager、PackageManager | 同步调用,返回结果直接可用 |
| 回调 / Listener | LocationManager、SensorManager | 服务端主动通知客户端,需注册与反注册 |
| 广播 / 系统事件 | 电池变化、网络切换 | 松耦合,适合一对多通知 |
| ContentProvider | 联系人、媒体库 | 基于 Binder,面向数据共享 |
| Messenger / AIDL | 自定义跨进程服务 | 应用自身实现服务端与客户端 |
五、案例:一次 startActivity 的完整链路
以 startActivity() 为例,应用进程中的 Activity 调用 startActivity(),最终会走到 Instrumentation.execStartActivity(),通过 ActivityManager.getService() 拿到 IActivityManager 代理,再调用 startActivity()。请求经 Binder 驱动进入 system_server,由 ActivityManagerService 完成权限检查、任务栈调度和进程启动决策。整个过程对应用开发者是透明的,但理解它有助于排查 SecurityException、RemoteException 以及启动超时等问题。
getSystemService() 返回的是服务对象本身,因而在子线程中随意调用或长期持有。实际上它只是代理,调用仍受 Binder 线程池和权限限制;在主线程执行耗时服务调用还可能引发 ANR。
六、复盘与要点清单
- 系统服务运行在 system_server,应用通过代理访问。
Context.getSystemService()是获取服务代理的标准入口。- Binder 负责跨进程传输,核心是
transact()与onTransact()。 - 交互方式包括直接调用、回调、广播、ContentProvider 和自定义 AIDL。
- 调用系统服务时要关注权限、线程模型和异常处理。
掌握系统服务架构、Context.getSystemService()、Binder 机制以及交互方式,就抓住了 Android 系统服务集成的“主干”。后续无论是申请权限、调用系统能力,还是扩展自定义系统服务,都会围绕这条链路展开。