Android进程间通信Binder 浅析
Android系统是基于Linux内核的,而Linux内核继承和兼容了丰富的Unix系统进程间通信(IPC)机制。 但是,Android系统没有采用上述提到的各种进程间通信机制,而是采用Binder机制。Binder是Android中使用最广泛的IPC机制。
前面一再提到,Binder是一种进程间通信机制,是提供远程过程调用(RPC)功能。从英文字面上意思看,Binder具有粘结剂的意思,那么它把什么东西粘结在一起呢?在Android系统的Binder机制中,由一系统组件组成,分别是Client、Server、Service Manager和Binder驱动程序,其中Client、Server和Service Manager运行在用户空间,Binder驱动程序运行内核空间。Binder就是一种把这四个组件粘合在一起的粘结剂了,其中,核心组件便是Binder驱动程序了,Service Manager提供了辅助管理的功能,Client和Server正是在Binder驱动和Service Manager提供的基础设施上,进行Client-Server之间的通信。Service Manager和Binder驱动已经在Android平台中实现好,开发者只要按照规范实现自己的Client和Server组件就可以了。
其实Binder中的各个元素,会发现和TCP/IP网络有很多的相似之处。
* Binder驱动——路由器
*Service Manager——DNS
*Binder Client——客户端
*Binder Server——服务器
TCP/IP中一个典型的服务连接过程(比如客户端通过浏览器访问Google主页)
*Client向DNS查询Google.com的IP地址
*DNS将查询结果返回给Client
*Client发起连接‘
*路由器将数据包投递到用户设定的目标IP中。
DNS角色并不是必须的,他的出现是为了帮助人们使复杂难记的IP地址与可读性更强的域名建立关联,并提供查询功能。
Binder就是进程1(客户端)希望与进程2(服务端)进行互访。但因为他们之间是跨进程的,所以必须借助于Binder驱动(路由器)来把请求正确投递到对方所在进程里。
Service Manager是DNS,IP地址是什么没呢?Service Manager在Binder通信过程中的唯一标识永远都是0.
Android系统Binder机制中的四个组件Client、Server、Service Manager和Binder驱动程序的关系如下图所示
1. Client、Server和Service Manager实现在用户空间中,Binder驱动程序实现在内核空间中
2. Binder驱动程序和Service Manager在Android平台中已经实现,开发者只需要在用户空间实现自己的Client和Server
3. Binder驱动程序提供设备文件/dev/binder与用户空间交互,Client、Server和Service Manager通过open和ioctl文件操作函数与Binder驱动程序进行通信
4. Client和Server之间的进程间通信通过Binder驱动程序间接实现
5. Service Manager是一个守护进程,用来管理Server,并向Client提供查询Server接口的能力
6. Binder驱动不需要硬件,或者说操作的硬件是基于一小段内存。由于其运行在内核态,客户端程序调用Binder是通过系统调用完成的。
服务端:一个Binder服务端实际就是一个Binder类的对象,该对象一旦创建,内部就启动一个隐藏线程。该线程接下来会接受Binder驱动发送的消息,收到消息后,会执行到Binder对象中的onTransact()函数,并按照该函数的参数执行不同的服务代码。因此要实现一个Binder服务,就必须重载onTransact()方法。
重载onTransact()函数的内容是把onTransact()函数的参数转换为服务函数的参数,而onTransact()函数的参数来源是客户端调用transact()函数时输入的,因此,如果transact()有固定格式的输入,那么onTransact()就会有固定格式的输出。
Binder驱动:任意一个服务端对象被创建时,同时会在Binder驱动中创建一个mRemote对象,该对象的类型也是BInder类。客户端要访问远程服务是,都是通过mRemote对象。mRemote对象重载了transact()方法,包括以下:
* 以线程间消息通信的模式,向服务端发送客户端传递过来的参数
* 挂起当前线程,当前线程正式客户端线程,并等待服务端线程执行完指定服务函数后通知(notify)
* 接受到服务端线程的通知,然后继续执行客户端线程,并返回到客户端代码区。
客户端:客户端要访问远程服务,必须获取远程服务在Binder对象中对应的mRemote引用。获得该mRemote对象后,就可以调用其transact()方法。
对应用程序开发来说,客户端似乎是直接调用远程服务对应的Binder,而事实上则是通过Binder驱动进行了中转。即存在两个Binder对象,一个是服务端的Binder对象,另一个Binder驱动中的Binder对象,所不同的是Binder驱动中的对象不会再额外产生一个线程。
更多学习:老罗的CSDN博客http://blog.csdn.net/luoshengyang/article/details/6618363
更多推荐
所有评论(0)