1 . binder 通信概述
binder 通信是一种 client-server 的通信结构,
1. 从表面上来看,是 client 通过获得一个 server 的代理接口,对 server 进行直接调用;
2. 实际上,代理接口中定义的方法与 server 中定义的方法是一一对应的;
3.client 调用某个代理接口中的方法时,代理接口的方法会将 client 传递的参数打包成为 Parcel 对象;
4. 代理接口将该 Parcel 发送给内核中的 binder driver.
5.server 会读取 binder driver 中的请求数据,如果是发送给自己的,解包 Parcel 对象,处理并将结果返回;
6. 整个的调用过程是一个同步过程,在 server 处理的时候, client 会 block 住。
2 . service manager
Service Manager 是一个 linux 级的进程 , 顾名思义,就是 service 的管理器。这里的 service 是什么概念呢?这里的 service 的概念和 init 过程中 init.rc 中的 service 是不同, init.rc 中的 service 是都是 linux 进程,但是这里的 service 它并不一定是一个进程,也就是说可能一个或多个 service 属于同一个 linux 进程。在这篇文章中不加特殊说明均指 android native 端的 service 。
任何 service 在被使用之前,均要向 SM(Service Manager) 注册,同时客户端需要访问某个 service 时,应该首先向 SM 查询是否存在该服务。如果 SM 存在这个 service ,那么会将该 service 的 handle 返回给 client , handle 是每个 service 的唯一标识符。
SM 的入口函数在 service_manager.c 中,下面是 SM 的代码部分
int main(int argc, char **argv)
{
struct binder_state *bs;
void *svcmgr = BINDER_SERVICE_MANAGER;
bs = binder_open(128*1024);
if (binder_become_context_manager(bs)) {
LOGE("cannot become context manager (%s)/n", strerror(errno));
return -1;
}
svcmgr_handle = svcmgr;
binder_loop(bs, svcmgr_handler);
return 0;
}
这个进程的主要工作如下:
1. 初始化 binder ,打开 /dev/binder 设备;在内存中为 binder 映射 128K 字节空间;
2. 指定 SM 对应的代理 binder 的 handle 为 0 ,当 client 尝试与 SM 通信时,需要创建一个 handle 为 0 的代理 binder ,这里的代理 binder 其实就是第一节中描述的那个代理接口;
3. 通知 binder driver(BD) 使 SM 成为 BD 的 context manager ;
4. 维护一个死循环,在这个死循环中,不停地去读内核中 binder driver ,查看是否有可读的内容;即是否有对 service 的操作要求 , 如果有,则调用 svcmgr_handler 回调来处理请求的操作。
5.SM 维护了一个 svclist 列表来存储 service 的信息。