Binder是跨进程内存访问,是Android中使用最广泛的IPC机制。
Binder由以下几部分组成:
对照TCP/IP中Client与Server服务连接过程:
让Client与Server连接需要以下几个步骤,以请求baidu.com为例:
假如进程间传递的数据是一个int类型数据,只要不断复制直到目标进程即可。那么,进程间传递的数据是一个对象,这时该怎么做?从所周知,在同一进程中传递数据是通过对象引用来做的,因而本质上传递的是内存的地址。由于采用了虚拟内存机制,两个进程都拥有自己独立的内存空间,跨进程传递的内存地址是无效的。
进程间传递数据是IBinder中重要一环,在Android中负责进程间传递数据的载体是Parcel,中文翻译是打包。
Parcel是一种载体,用于承载通过IBinder发送的数据相关信息(包括数据和对象引用)。在跨进程中传递内存地址这种方式是无效的,那么,将进程A中的对象的相关数据信息打包,传递到进程B中,再由进程B将数据“复现”。而Parcel就有将数据打包和重组的能力。
Android系统基于Linux内核,因而它所依赖的Binder驱动也是一个标准Linux驱动。Binder Driver会将自己注册成一个misc device,并向上层提供一个/dev/binder节点,值得一提的是Binder节点并对应真实的硬件设备。Binder驱动运行于内核态,并提供oper()、ioctl()、mmap()等文件操作函数。
PS:个人理解,就是Binder驱动通过文件操作函数,在物理内存中申请一块区域,并将这块物理内存映射到虚拟内存中,并且这个物理内存是一块共享内存区,这样就通过一次数据复制就做到了跨进程的数据传递。因为,其它进程也可以访问这块共享的物理内存。
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驱动中获取的。
PS:Binder进阶
原文:https://www.cnblogs.com/naray/p/7088311.html