Android进程间通信Binder 浅析

       Android中,每一个应用程序都是由一些Activity和Service组成的,这些Activity和Service有可能运行在同一个进程中,也有可能运行在不同的进程中。那么,不在同一个进程的Activity或者Service是如何通信的呢?这就是本文中要介绍的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
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值