Binder机制自己理解

binder 是Android一种进程间通信的一种方式,他是基于c-s 框架的通信方式。

binder通信基本分为4个对象,1.client 客户端 2.service 服务端 3,service manger 服务管理对象,4,binder 驱动

其实客户端和服务端是相当概念,比如 AMS PMS senorService 等一些概念,如果相当于我们自己的应用时,他就是服务端,我们自己的应用就是客户端,通过binder 来进行通信,,而如果是ams pms 等在初始化的时候,那么他需要通过binder 进行关联到service manger ,然后在service manger中进行注册服务,那么ams pms 就是客户端,而service manger 就是服务端

最早和binder 进行通信的是 service manger ,他是在 手机开机的时候,,在调用 BootLoader —jvm —init.rc 进行初始化文件读写的时候,就会启动 service manger 的服务,调用过程为:

先通过 IserviceManger 的类 调用 defaultServiceManger () ----ProcessState 中会获得 processstate 对象,,,然后直接调用binder.c 里面的方法 :
1.open_deiver(): 进行驱动的打开 —在文件打开之后就会为当前的servicemanger 创建一个struct binder_proc 结构体来维护 进程的上下文相关信息。

2.在文件打开之后会调用 binder_ioctl 函数,第一会为当前的线程创建一个struct binder_thread 结构体变量来维护线程上下文信息, 在将传递参数保存到 proc->max_thread 中,之后如果在用的这个线程则冲proce_thread 的红黑树进行获取,其中 binder_proc 中也有一个 node的红黑树,是用来保存 binder 的实体,ref_by_desc 和ref_by_node 是用来保存binder的引用实体。。

3.mmap 方法的调用,进行空间的分配,当mmap函数调用完成之后,就会得到一个内存映射地址空间,这个地址空间被划出一段一段来管理,每一段就是结构体 struct binder_buffer 来描述,每个binder_buffer 通过其成员entry按从低址到高址连接到binder_procss 中的buffers 表示的链表中去,同时,每一个binder_buffer又分为正在使用的和空闲的,通过free 成员变量来区分,空闲的binder_buffer 通过rb_node 连接到struct binder_proc中的free_buffer 表示的红黑树中,正在使用的binder_buffer 通过rb_node 连接到allocate_buffer 表示的红黑树中,这样做事为了方便查询和维护这块空间。

4.调用binder_become_context_manger 来通知binder驱动程序自己是binder的上下文管理者,即守护进程,这个也是通过调用ioctl 的方法通知binder,命令是: BINDER_SET_CONTEXT_MSG,其中有两个数据结构: struct binder_thread ,他表示一个线程 ,在binder_proc 中有一个threads ,他的类型是rb_root,表示一个红黑树,把所以的属于这个进程的线程都组织起来,
另一个数据结构是: struct binder_node ,他表示binder实体
其成员变量: rb_node 和dead_node 组成一个联合体,如果这个binder实体还在正常使用,则使用rb_node 来连入 proc_node ,所表示的红黑树节点,这棵树用来组织属于这个进程的所有binder实体,如果这个binder实体所属的进程已经销毁,而这个binder实体有被其他进程所引用,则这个binder实体通过dead_node 进入到一个哈希表中去存放,proc 成员变量表示这个binder实体的所属的进程,

5.开始调用 binder_loop函数进入循环等待cline 来的请求,首先通过binder_write 函数执行BC_ENTER_LOOPER 命令告诉binder驱动程序,service manger 要进入循环,说明: 用户空间程序和binder驱动程序交互大多数都是通过binder_write_read 命令的,write_buffer 和read_buffer 所指向的数据结构还指定了具体的要执行的炒作,当这个binder_write_read 命令的目标对象是本地binder实体时,则用ptr来表示这个对象在本进程中的地址,否则就使用handler来表示这个binder实体的引用, 从binder驱动中进行获取数据,然后通过 binder_parse() 进行获取到的数据的解析,然后 处理消息 svcmsg_handler :其中进行调用 do_add_service () 和do_find_service() 的方法

获取service manger :
如果需要获取servicemanger ,肯定是在另一个进程中进行的,则需要创建出一个binder 对象,

先通过本地的代理对象,,IserviceManger 对象调用 defaultServiceManger() 其中 会调用 ProcessState:: self() —new ProcessState —opendevice —ioctl ()–mmap() ----getcontextObject — getstrongproxyForHandle() —lookupHandleLocked(0)----new Bpbinder() —interface _cast

----IserviceManger::asInterface() —new BpServiceManger();

//当得到ServiceManger 对象后则进行添加服务

如:MediaPlayService 添加到service中是:
Binder机制自己理解_第1张图片

binder 机制架构图
Binder机制自己理解_第2张图片
获取ServiceManger 流程图
Binder机制自己理解_第3张图片

启动servicemanger 流程图
Binder机制自己理解_第4张图片

你可能感兴趣的:(Binder机制自己理解)