Binder的C语言实现

69 阅读2分钟

一、Binder是什么?

你可以把Binder理解为Android系统的"电话系统"。就像打电话时,A可以呼叫B的手机来沟通一样,Binder让不同App(进程)之间能互相"打电话"(通信)。

关键角色:

  1. ​服务端(Server)​​:像接电话的人,提供具体服务
  2. ​客户端(Client)​​:像打电话的人,需要获取服务
  3. ​ServiceManager​​:像电话簿,记录所有服务的联系方式
  4. ​Binder驱动​​:像基站,负责信号传输

二、Binder通信的核心步骤

1. 服务注册(存号码)

服务端将服务信息(如"天气查询")和联系方式注册到ServiceManager:

c
Copy
// 相当于说:"把我的天气查询服务存进电话簿"
svcmgr_publish(bs, svcmgr, "weather", weather_service_handler);

2. 服务查找(查号码)

客户端通过ServiceManager查找服务:

c
Copy
// 相当于查电话簿:"天气查询服务的号码是多少?"
handle = svcmgr_lookup(bs, svcmgr, "weather");

3. 远程调用(打电话)

客户端通过获取的"号码"调用服务:

c
Copy
// 相当于拨打查到的号码:"请问今天北京天气如何?"
binder_call(bs, &msg, &reply, handle, GET_WEATHER);

三、关键代码解析(比喻版)

1. 服务端代码

c
Copy
void sayhello() { /* 具体服务实现 */ }

int handler(...) {
    switch(指令类型) {
    case 问好: 
        sayhello(); // 执行问好服务
        bio_put_uint32(reply, 0); // 回复"没问题"
        break;
    }
}

就像服务员随身携带对讲机,随时等待客户呼叫。

2. 客户端代码

c
Copy
void 远程问好() {
    打包问题("我想问好"); // 把请求装信封
    binder_call(...); // 寄出信封
    拆解回信(); // 读取回复
}

就像顾客填写服务申请表,投递到服务窗口。


四、底层驱动如何工作?

Binder驱动相当于邮局系统,处理三个核心操作:

  1. ​open()​​ - 打开邮局
  2. ​mmap()​​ - 准备信箱(内存映射)
  3. ​ioctl()​​ - 实际收发信件

驱动确保信件能跨进程安全传递,就像邮局处理不同国家的邮件分拣。


五、完整流程图示

客户端 -> ServiceManager:老张的电话多少?
ServiceManager -> 客户端:123456
客户端 --Binder驱动--> 服务端:老张,帮我修电脑!
服务端 --Binder驱动--> 客户端:修好了!

六、学习要点

  1. ​三个角色​​:理解服务端、客户端、ServiceManager的分工
  2. ​两个过程​​:服务注册与远程调用
  3. ​数据打包​​:像填写快递单,要按规定格式封装数据
  4. ​驱动交互​​:掌握open/mmap/ioctl这三个关键系统调用

建议在Linux环境下实际运行示例代码,观察logcat输出,能更直观理解通信过程。

通过这个比喻,是否对Binder的C语言实现有了更清晰的认识呢?这为后续学习Java层的Binder封装打下了基础。