Android Binder机制的服务获取与使用过程

111 阅读3分钟

一、Binder通信的比喻

可以把Binder机制想象成打电话:

  • ​ServiceManager​​ 是电话黄页(服务目录)
  • ​服务​​(如"hello服务")是某个公司的电话号码
  • ​Handle值​​ 是电话号码的数字编码
  • ​Binder驱动​​ 是电话交换机,负责连接通话双方

二、获取服务的过程(查黄页)

  1. ​客户端请求​​:

    • 客户端调用svcmgr_lookup("hello"),相当于查黄页说:"我要找hello服务的电话号码"
    • 构造数据包:包含服务名"hello"和请求类型SVC_MGR_CHECK_SERVICE
  2. ​内核处理​​:

    • Binder驱动通过ioctl系统调用接收请求
    • 找到ServiceManager进程(固定handle=0)
    • 把请求数据打包快递给ServiceManager
  3. ​ServiceManager响应​​:

    • ServiceManager在自己的服务列表中找到"hello"对应的handle
    • 返回数据包:包含handle值和特殊标识BINDER_TYPE_HANDLE
  4. ​内核转换​​:

    • Binder驱动为客户端创建新的handle(类似分机号)
    • 建立客户端handle与服务进程的映射关系
  5. ​客户端获得handle​​:

    • 最终客户端拿到一个数字(如#9527),这个数字就代表目标服务

三、使用服务的过程(打电话)

  1. ​构造请求​​:

    • 用获得的handle(#9527)作为"电话号码"
    • 打包数据:包含方法名HELLO_SVR_CMD_SAYHELLO和参数
  2. ​内核路由​​:

    • Binder驱动通过handle找到目标服务进程
    • 检查权限,建立客户端与服务端的通信管道
  3. ​服务端处理​​:

    • 服务端进程被唤醒,执行具体的sayHello()方法
    • 处理结果通过管道返回(如返回状态码0表示成功)
  4. ​客户端接收结果​​:

    • 客户端从阻塞中恢复,解析返回数据
    • 完成一次完整的远程方法调用

四、核心机制揭秘

  1. ​Handle的魔法​​:

    • 每个handle对应内核中的一个binder_ref结构体
    • 类似快递单号,内核通过它找到对应的服务进程
  2. ​数据快递系统​​:

    • 所有数据通过binder_io结构体打包
    • 驱动使用binder_transaction_data结构传输数据
    • 自动处理不同进程间的内存映射
  3. ​进程调度​​:

    • 调用方进程会被挂起(进入睡眠状态)
    • 被调用方进程被唤醒处理请求
    • 类似接电话时的等待和应答

五、为什么需要Binder驱动?

  1. ​安全卫士​​:

    • 验证调用方的权限
    • 管理进程间的访问权限
  2. ​地址翻译官​​:

    • 将应用层的handle转换为内核地址
    • 处理不同进程间的内存隔离
  3. ​通信调度中心​​:

    • 维护红黑树快速查找服务
    • 管理线程的阻塞/唤醒状态

六、日常开发类比

  • ​获取服务​​:就像用美团找餐厅,得到店铺ID
  • ​使用服务​​:就像用店铺ID下单,美团后台帮你联系商家
  • Binder驱动就是美团的后台系统,处理所有对接细节

通过这种机制,Android实现了:
✅ 跨进程通信的安全管控
✅ 高效的服务发现机制
✅ 透明的远程方法调用