Android Binder-框架简析
来源:互联网 发布:ubuntu如何设置ip地址 编辑:程序博客网 时间:2024/06/08 13:16
Android这个庞大的系统中会涉及非常多的进程间通信,是什么让各个进程间通信起来毫无障碍且有条不紊的呢?传统的IPC(即”进程间的通信”缩写),例如Pipe和Socket,执行一次通信需要两次数据的拷贝,举个例子如,Client要将一块内存数据传递给Server,一般的做法是,Client将这块数据从它的进程空间拷贝到内核空间中,然后内核再将这个数据从内核空间拷贝到Server的进程空间,这样,Server就可以访问这个数据了,但是在这种方法中,执行了两次内存拷贝操作。而采用Binder机制,只需要把Client进程空间的数据拷贝一次到内核空间,然后Server与内核共享这个数据就可以了,整个过程只需要执行一次内存拷贝,提高了效率。Binder的主要核心有两部分,分别是IPC(进程间通信)和RPC(远程过程调用)。
IPC
进程间的通信,以AB两个进程间通信作为例子,数据传输有三要素:- 源:A进程(要去访问B进程提供的LED驱动接口)
- 目的: B进程(进程A是如何得知是进程B提供LED访问呢?):
B进程向ServiceManager注册led服务
A进程向ServiceManager查询led服务,得到一个handle(句柄) - 数据传输:使用buffer
RPC
远程调用(在IPC的基础上做了层封装),例如调用led_open / led_ctl,但它并没有权限,所以需要做如下处理:- 封装(构造)数据
- A进程发送数据(通过IPC通道发送给B进程),B进程会取出数据然后调用led_open / led_ctl,就好像A直接操作LED一样
RPC:远程调用涉及的过程:
- 调用哪一个函数:根据Server的函数编号(led_ctl、led_open)
- 传给给它什么参数:通过IPC的buffer传输(哪个灯,亮还是灭)
- 返回值:通过IPC的buffer传输(返回成功与否)
Binder系统涉及4个部分:
1. Client(如上文提及的A进程),程序操作如下:
- Open binder驱动(涉及进程间的通信都需要open)
- 获取服务
a) 向servicemanager查询服务
b) 获得一个handle(句柄) - 向handle发数据
2. ServiceManager(一个特殊的service,告诉A如何找到B),程序操作如下:
- Open binder驱动
- 告诉binder驱动程序,它是ServiceManager
- While循环,读驱动获取数据,解析数据,调用下面两个函数
a) Server注册服务(在链表中记录服务名)
b) Client获取服务
i. 在链表中查询有无服务
ii. 返回server进程的handle
3. Server(上文提及的B进程),程序操作如下:
- Open binder 驱动
- 注册服务
a) 向servicemanager发送服务名 - While循环,读驱动,解析数据,调用对应的函数
4. Binder(上面三部分的通信通过binder驱动实现)
下面用系统自带的binder程序来理解整个调用过程,代码是使用C语言来实现的,它在系统文件中的目录如下:
android\frameworks\native\cmds\servicemanager\
调用过程分析只涉及下面三个文件:
service_manager.c
bctest.c(半成品,可以根据它写出我们的Client和Server程序)
binder.c(封装好的C库)
上面三个文件整个调用过程对应的源码简析如下:
************************************** service_manager.c **************************************a. binder_openb. binder_become_context_managerc. binder_loop(bs, svcmgr_handler); c.1 res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr); c.2 binder_parse // 解析 // 处理 : svcmgr_handler SVC_MGR_GET_SERVICE/SVC_MGR_CHECK_SERVICE : 获取服务 SVC_MGR_ADD_SERVICE : 注册服务 // 回复
******************************************* bctest.c *******************************************注册服务的过程:a. binder_openb. binder_call (bs, &msg, &reply, 0, SVC_MGR_ADD_SERVICE)// bs: 打开的device的binder fd // msg: 含有服务的名字// reply: 它会含有servicemanager回复的数据 // 0: 表示servicemanager// SVC_MGR_ADD_SERVICE(code): 表示要调用servicemanager中的"addservice函数"获取服务的过程:a. binder_openb. binder_call(bs, &msg, &reply, target, SVC_MGR_CHECK_SERVICE)// bs: 打开的device的binder fd // msg: 含有服务的名字,表示要获得哪一个名字// reply: 它会含有servicemanager回复的数据, 表示提供服务的进程// target :里面是0,表示servicemanager// SVC_MGR_CHECK_SERVICE(code): 表示要调用servicemanager中的"checkservice函数"
******************************************* binder.c *******************************************binder_call:远程调用int binder_call(struct binder_state *bs, struct binder_io *msg, struct binder_io *reply, uint32_t target, uint32_t code)//target :向谁发数据//code:调用哪个函数//msg:提供什么参数//reply:返回值binder_call最终会构造一个binder_write_read结构体,然后调用ioctl发送出去struct binder_write_read { binder_size_t write_size; /* bytes to write */ binder_size_t write_consumed; /* bytes consumed by driver */ binder_uintptr_t write_buffer; binder_size_t read_size; /* bytes to read */ binder_size_t read_consumed; /* bytes consumed by driver */ binder_uintptr_t read_buffer;};Read_buffer里面调用binder_transaction_data(形参里面有code和用户构造的参数),根据code可以决定调用什么函数如何使用binder进行数据传输:1. 构造参数:一般放在buf里面,有个结构体叫binder_io来描述2. 调用ioctl来发数据res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);3. Ioctl不仅能发数据,也可以收数据,收到一个binder_write_read结构体数据,需要转换为binder_io(即将收到的数据构造成一个binder_io)
怎么写APP:
- client
a) binder_open
b) 获得服务:handle
c) 构造参数:binder_io
d) 调用binder_call函数,形参中包含:handle(发给哪个进程),code(想调用进程的哪个函数),binder_io(发送的参数)
e) binder_call会返回binder_io,取出返回值 - server
a) binder_open
b) 注册服务
c) ioctl(这里会读到client发来的数据,会读到handle,code, binder_io这些参数)
d) 解析数据得出code和参数
binder_write_read. read_buffer->binder_transaction_data->code 和 参数,这个参数会转换为binder_io
e) 根据code,决定调用哪个函数,从binder_io取出参数,这个参数是传给调用的那个函数的
f) 把返回值再次转换为binder_io发给client,client就可以从binder_call得到这个binder_io了
下一章会具体实现编写代码的过程
- Android Binder-框架简析
- Android Binder 框架
- android的Binder框架
- Android - Binder机制 - Binder框架总结
- Android - Binder机制 - Binder框架总结
- Android aidl Binder框架浅析
- Android aidl Binder框架浅析
- Android aidl Binder框架浅析
- Android aidl Binder框架浅析
- Android aidl Binder框架浅析
- Android aidl Binder框架浅析
- Android aidl Binder框架浅析
- Android aidl Binder框架浅析
- Android aidl Binder框架浅析
- Android aidl Binder框架浅析
- Android aidl Binder框架浅析
- Android Binder 框架层详解
- Android AIDL Binder框架浅析
- 福州大学2271x——弗洛伊德最短路
- Android动画解析(一)
- 模仿最新版爱奇艺卡片式轮播效果CardBannerDemo
- 带你玩转Netty(二)
- Android中ASE加密算法工具类
- Android Binder-框架简析
- 2017百度之星资格赛1003 度度熊与邪恶大魔王(完全背包)
- Unity3D之进度条插件Loading Component
- HDU4686 Arc of Dream 矩阵快速幂
- HDUOJ 2072单词数
- 【C++】字符串的长度、大小
- java笔记
- 使用xml配置组装bean
- Android笔面