Android Java系统服务框架及如何让第三方App使用自定义的Java系统服务

121 阅读2分钟

用通俗易懂的方式讲解这篇文章的核心内容,重点结合Binder机制:

第一部分:Android系统服务框架(以振动服务为例)

  1. ​基本结构​​:

    • 应用层看到的Vibrator其实是个"空壳"抽象类,真正干活的是背后的SystemVibrator
    • 就像你去餐厅点餐,服务员(SystemVibrator)负责把你的请求传给后厨(VibratorService)。
  2. ​Binder通信过程​​:

    • 当App调用vibrate()时,SystemVibrator通过IVibratorService这个"电话"(Binder代理对象)打给系统服务。

    • 系统服务VibratorService继承自IVibratorService.Stub,相当于专门接电话的服务员。

    • 整个过程就像:

      应用 --> SystemVibrator --> Binder驱动 --> VibratorService --> 硬件振动
      
  3. ​服务启动​​:

    • 系统开机时,SystemServer这个大管家会启动各种服务,包括new VibratorService()
    • 然后把这个服务登记到"电话簿"里:ServiceManager.addService("vibrator", vibrator)

第二部分:自定义服务与第三方调用

  1. ​标准服务模板​​:

    • 服务端:继承Xxx.Stub实现功能
    • 客户端:通过Xxx.Stub.asInterface()获取代理
    • 必须通过SystemServiceRegistry注册服务名称,否则普通App找不到
  2. ​关键改造点​​:

    • ​Binder接口设计​​:必须用AIDL定义接口,生成对应的Stub/Proxy类

    • ​服务注册​​:在Android核心登记处SystemServiceRegistry添加新服务

    • ​权限突破​​:

      • 修改hiddenapi名单让普通App能调用系统级API
      • 生成包含自定义类的framework.jar供App引用
      • SELinux策略允许第三方应用查找服务
  3. ​常见问题解决​​:

    • 如果App报错找不到类:检查framework.jar是否包含完整路径
    • 如果权限拒绝:检查SELinux策略是否添加allow untrusted_app相关规则
    • 如果调用无反应:检查服务是否成功注册到ServiceManager

Binder的核心作用

可以想象Binder就像一套完整的电话系统:

  • ServiceManager是总机,记录所有服务分机号
  • AIDL生成的代码是标准通话协议
  • Stub是接电话的一方,Proxy是打电话的一方
  • Binder驱动是电话交换机,负责建立连接

通过这种机制,Android实现了:

  1. 严格的权限管控(只有登记的服务才能被调用)
  2. 高效的跨进程通信(不需要自己处理复杂的IPC)
  3. 客户端与服务端的完全解耦(只要通话协议不变,内部实现可随意修改)

建议动手实践时,重点注意:

  1. 服务命名字符串必须完全一致(客户端/服务端/注册时)
  2. 注意Android版本差异(特别是hiddenapi处理方式)
  3. 使用adb shell service list命令验证服务是否注册成功

这样改造后的自定义服务,就能像系统自带的振动服务一样被任何App调用了,整个过程充分体现了Binder在Android系统架构中的桥梁作用。