一、简介:
Binder是跨进程内存访问,是Android中使用最广泛的IPC机制。
Binder由以下几部分组成:
-
- Binder驱动
- Binder Manager
- Binder Client
- Binder Service
对照TCP/IP中Client与Server服务连接过程:
- Binder驱动 -- 路由器(Router)
- Binder Manager -- DNS 服务器
- Binder Client -- Client
- Binder Server -- Server
让Client与Server连接需要以下几个步骤,以请求baidu.com为例:
- 首先,Cleint向DNS域名服务器发起请求,请求查询指定baidu.com的IP地址,并返回给Client。
- 然后,Client通过从DNS获取的IP地址,向baidu.com发起连接。在整个过程中都没提起Router的作用,它担负的责任是将数据包投递到用户指定的目标IP中,即Router是整个通信结构的基础。
二、进程间数据传递载体 -- Parcel
假如进程间传递的数据是一个int类型数据,只要不断复制直到目标进程即可。那么,进程间传递的数据是一个对象,这时该怎么做?从所周知,在同一进程中传递数据是通过对象引用来做的,因而本质上传递的是内存的地址。由于采用了虚拟内存机制,两个进程都拥有自己独立的内存空间,跨进程传递的内存地址是无效的。
进程间传递数据是IBinder中重要一环,在Android中负责进程间传递数据的载体是Parcel,中文翻译是打包。
Parcel是一种载体,用于承载通过IBinder发送的数据相关信息(包括数据和对象引用)。在跨进程中传递内存地址这种方式是无效的,那么,将进程A中的对象的相关数据信息打包,传递到进程B中,再由进程B将数据“复现”。而Parcel就有将数据打包和重组的能力。
三、Binder驱动
Android系统基于Linux内核,因而它所依赖的Binder驱动也是一个标准Linux驱动。Binder Driver会将自己注册成一个misc device,并向上层提供一个/dev/binder节点,值得一提的是Binder节点并对应真实的硬件设备。Binder驱动运行于内核态,并提供oper()、ioctl()、mmap()等文件操作函数。
PS:个人理解,就是Binder驱动通过文件操作函数,在物理内存中申请一块区域,并将这块物理内存映射到虚拟内存中,并且这个物理内存是一块共享内存区,这样就通过一次数据复制就做到了跨进程的数据传递。因为,其它进程也可以访问这块共享的物理内存。
四、“DNS”服务器 -- Service Manager(Binder Manager [Binder Server])
Service Manager的功能类拟于互联网中的DNS服务器,IP地址为“0”。和DNS本身也是服务器一样,Service Manager也是一个标准的Binder Server。在整个Android系统中只允许有一个Binder的Service Manager存在,因而在后面还有人调用binder_become_context_manager(...)函数就会调用失败。在Android系统启动时,Service Manager就会被启动。
Service Manager在启动时,做了以下几件事:
1. 打开Binder设备(/dev/binder),做好初始化。
2. 将自己设置为Binder的“大管家”,即Service Manager。
3. 进入主循环,等待客户端消息。
Service Manager在完成启动后,一切准备就绪,在消息的处理上和典型的基于事件驱动的程序循环框架类似:
-
- 从消息队列中读取消息。
- 如果消息是“退出命令”,则马上结束循环;如果消息是空,则继续读取消息或者等待一段时间后再读取消息;如果消息不是空并且消息不是退出命令,则根据消息的具体情况处理。
- 如此循环往复直到退出。
不过Service Manager中没有消息队列,它的“消息”或者称“命令”是从Binder驱动中获取的。
五、Binder Client
PS:Binder进阶