Android 系统中跨进程通信(Binder机制)在 C++ 层的实现原理

214 阅读3分钟

一句话概括

这篇文章讲解Android 系统中跨进程通信(Binder机制)在 C++ 层的实现原理,主要拆解了三个关键角色:协议类(菜单)、服务端(厨师)、客户端(顾客)。


形象比喻

想象一家餐厅的运作:

  1. ​协议类(IHelloService)​​:就像一份菜单,定义了"打招呼"和"向某人打招呼"两个服务项目
  2. ​服务端(BnHelloService)​​:后厨的厨师,真正实现做菜(具体业务逻辑)
  3. ​客户端(BpHelloService)​​:餐厅前台的接单员,负责把顾客需求转达给后厨
  4. ​Binder驱动​​:相当于传菜员,负责在厨师和接单员之间传递信息

核心组件详解

1. 协议类(菜单)

cpp
Copy
class IHelloService: public IInterface {
    virtual void sayHello() = 0;          // 定义打招呼服务
    virtual int sayHelloTo(name) = 0;     // 定义带参数的打招呼服务
};
  • ​作用​​:定义服务接口(就像菜单列出的菜品)

  • ​特点​​:

    • 继承自IInterface,具备转换为Binder对象的能力
    • 使用DECLARE_META_INTERFACE宏生成辅助代码,方便接口转换

2. 服务端实现(厨师)

cpp
Copy
class BnHelloService: public BnInterface<IHelloService> {
    status_t onTransact(...) { // 处理来自客户的请求
        switch(请求类型) {
            case 打招呼: 执行sayHello();
            case 带参数打招呼: 执行sayHelloTo(name);
        }
    }
    // 实际业务实现
    void sayHello() { ALOGI("Hello!"); } 
};
  • ​继承结构​​:

    • BnInterface:组合了协议接口和Binder基础功能
    • BBinder:本地Binder对象,处理跨进程请求的基类
  • ​关键方法​​:

    • onTransact:收到请求时的处理中心(类似厨师的做菜流程)
    • 实际服务方法:真正执行业务逻辑的地方

3. 客户端代理(接单员)

cpp
Copy
class BpHelloService: public BpInterface<IHelloService> {
    void sayHello() {
        打包数据->通过BpBinder发送请求->接收结果
    }
};
  • ​核心组成​​:

    • BpInterface:组合协议接口和代理功能
    • BpRefBase:持有BpBinder(实际通信工具)
  • ​工作流程​​:

    1. 将方法调用打包成数据包(Parcel)
    2. 通过BpBinder发送给服务端
    3. 接收返回结果并解析

核心类关系图

客户端                                服务端
BpHelloService -> BpBinder ------> BBinder <- BnHelloService
       ↑                               ↑
       └── 共用协议接口 IHelloService ──┘

工作流程示例(以打招呼为例)

  1. ​客户端调用​​:

    cpp
    Copy
    helloService->sayHello();
    
  2. ​数据打包​​:将方法名、参数打包成Parcel数据包

  3. ​跨进程发送​​:通过BpBinder发送请求码(HELLO_SVR_CMD_SAYHELLO)

  4. ​服务端处理​​:

    • Binder驱动将请求路由到正确的BBinder
    • 触发onTransact方法,解析请求码
    • 调用真正的sayHello()实现
  5. ​结果返回​​:将执行结果打包返回客户端


关键设计思想

  1. ​接口与实现分离​​:通过协议接口实现客户端/服务端解耦
  2. ​代理模式​​:客户端通过代理对象访问远程服务
  3. ​数据序列化​​:使用Parcel进行数据打包/解包
  4. ​请求路由​​:通过transaction code区分不同服务方法

这种设计使得Android系统可以优雅地实现跨进程通信,开发者只需要关注业务逻辑的实现,复杂的通信细节都由Binder框架自动处理。