Binder 学习http://blog.csdn.net/ylyuanlu/article/details/6629332java
Binder 的应用模型c++
一个IPC通信咱们能够简单的理解成客户端-服务器模式,客户端请求服务,服务端接收到客户端请求后处理相应的请求,或可能带回结果返回给客户端。Binder机制在Android系统的进程间通信模型总结以下:编程
1)客户端经过某种方式获得服务器端的代理对象。从客户端角度看来代理对象和他的本地对象没有什么差异。他能够像其余本地对象同样调用其方法,访问其变量。数组
2)客户端经过调用代理对象的方法向服务器端发送请求信息。服务器
3)代理对象经过binder设备节点(/dev/binder),把用户请求信息发送到Linux内核空间(实际上市内存共享),由binder驱动获取并发送到服务进程。并发
4)服务器进程处理用户请求,并经过Linux内核的binder驱动返回处理结果给客户端的代理对象。框架
5)客户端收到服务端的返回结果。函数
整个过程大体如上所述,能够想象一下binder机制的引入,给进程间的通信带来什么好处?没错就是线程迁移,就像是一个线程带着参数,进入另外一个进程执行,而后带着结果返回,和调用本身的函数同样的效果。oop
Binder机制的组成学习
1)binder驱动:binder是内核中的一个字符驱动设备位于/dev/binder。这个设备是Android系统IPC的核心部分,客户端的代理服务来经过它想服务器(server)发送请求,服务器也是经过它把处理结果返回给客户端的服务代理。这部份内容,在Android中经过一个IPCThreadState对象封装了对Binder驱动的操做。
2)Service Manager:这个东西主要用来负责管理服务。Android中提供的系统服务都要经过Service Manager注册本身,将本身添加进服务管理链表中,为客户提供服务服务。而客户端若是要和特定的系统服务端通信,就要向Service Manager来查询和得到所须要服务。能够看出Service Manager是系统服务对象的管理中心。
3)服务(Server):须要强调的是这里服务是指的是System Server,而不是SDK Server,向客户端提供服务。
4)客户端:通常是指Android系统上面的应用程序。它能够请求Server中的服务。
5)代理对象:是指在客户端应用程序中获取生成的Server代理(proxy)类对象。从应用程序角度看代理对象和本地对象没有差异,均可以调用其方法,方法都是同步的,而且返回相应的结果。
Binder机制的实现使用c c++实现的,但在Android的应用程序中,也会有java部分的内容。
Binder 之Service Manager
Service Manager在Android binder机制中的地位是至关的重要,全部的Server(System Server)都要向他注册,应用程序须要向其查询相应的服务。
service_manager.c是Service Manager的入口
int main(int argc, char **argv)
{
struct binder_state *bs;
void *svcmgr = BINDER_SERVICE_MANAGER;
bs = binder_open(128*1024);//打开binder设备,而后将该文件映射到内存中,并返回这块内存的首地址这样咱们就能够像操做内存同样,来操做这个文件了。
if (binder_become_context_manager(bs)) {//这个函数就是调用binder的ioctl设置成服务大管家。
ALOGE("cannot become context manager (%s)\n", strerror(errno));
return -1;
}
svcmgr_handle = svcmgr;
binder_loop(bs, svcmgr_handler);//Service Manager的核心-循环体,调用一个回调函数,处理不一样的请求
return 0;
}
Binder 之 服务代理对象
服务代理对象的应用模型:
1)首先客户端向Service Manager查找相应的Service
2)Android系统的binder机制将会为客户端进程建立一个Service代理
3)客户端视角只有Service代理,他全部对Service的请求都发往Service代理,而后由Service代理把用户请求转发给Service自己
4)Service处理完成后,吧结果返回给Service代理,Service代理负责把结果返回给客户端
在Android系统中的任何进程,要想使用binder机制,必需要建立一个ProcessState对象和IPCThreadState对象。
咱们知道一个客户端进程可能有多个Service的服务,这样就会建立多个Service代理(BPBinder对象),那么这个进程就须要一个东东来管理这些服务代理。ProcessState就是这个东东,它的做用就是维护当前进程中的全部Service代理。
defaultServiceManager生成一个IserviceManager对象sm,即Service Manager的服务代理,进程就是经过这个代理对象sm和Service Manager通信的,提供给本进程的其余服务器端或客户端访问Service Manager的接口。
Binder 的服务代理对象步骤:
1)建立ProcessState对象,用来管理本进程中获取的服务代理对象(根据客户端传的值),每一个进程智能建立一个该对象。
2)获取了Service Manager的服务代理对象,能够经过这个对象和服务管家通信了
3)实例化一些服务,并经过Service Manager代理对象向服务管家添加这些服务
4)服务端准备好了,就进入循环状态,接收来自客户端的请求
IPCThreadState对象的做用:
1)维护当前进程中全部对/dev/binder的读写,就是说当前进程经过binder机制进行跨进程条用都是经过IPCThreadState对象完成的
2)IPCThreadState也能够理解成/dev/binder设备的封装,用户能够不直接经过ioctl来操做binder设备
3)这个对象里确定有循环的从binder设备中拿信息,而后处理
4)若是是客户端进程,则经过服务代理BpBinder对象,调用transact函数,该函数做用就是把客户端的请求写入binder设备另外一端的Service进程
5)做为Service进程,当他完成初始化工做以后,他们须要进入循环状态等待客户端的请求,Service进程调用他的IPCThreadState对象的joinThreadPool方法,开始轮询binder设备,等待客户端请求的到来
Binder 客户端
整个服务代理的获取过程也是binder机制的核心内容,它涉及了客户请求,请求的传递和处理,服务代理的生成和转换(封装)过程。当客户端获取到对应服务的代理后,就能够经过这个服务代理和服务通信了。
Binder机制中的java层
咱们知道Android中的应用程序基本上都是java开发,对Android的框架了解的朋友都知道,java的本地实现都是经过jni层的接口来调用C/C++代码的,这里也不例外。在Android的binder机制中,java层面的binder机制的应用,你能够简单看做是底层binder机制的封装。
1)ServiceManager类型和对象
咱们都知道做为客户端要想得到服务代理,首相要建立ServiceManager代理对象,查询Service,而后建立并返回服务代理对象,再经过代理对象和Service通信。
查看源码ServiceManager就是IServiceManager对象的一个代理,他就是客户端代理对象的一个封装,由于建立和访问这个代理对象都是经过ServiceManager的getIServiceManager方法,咱们建立ServiceManager服务对象,是经过jni调用native代码,就是java的本地接口,来和底层的C/C++实现挂钩。建立一个服务代理对象BpBinder,在native层,BpBinder继承IBinder接口,把native层的IBinder对象封装成java层的IBinder对象。以后根据描述符,查找BpBinder对应的本地服务代理对象并转换为IserviceManager类型
Binder之编程模型
1)在service_manager.c的结构数组allowed中添加新的服务名称
2)定义一个继承IInterface接口的ImyService.h
Class ImyService:public IInterface
{
Public:
DECLARE_META_INTERFACE(MyService);//重要的地方就是,这个宏定义和下个宏
....虚函数
}
3)跟着在ImyService.h中定义本地实现类BnMyService,须要继承BnInterface,间接继承了IMyService和BBinder
Class BnMyService:public BnInterface<IMyService>
{
virtual status_t onTransact();
}
4)在IMyService.cpp中,定义接口代理类BpMyService,须要继承BpInterface
Class BpMyService:public BpInterface<IMyService>
{
Public:
BpMyservice(const sp<IBinder>& impl)
:BpInterface<IMyService>(impl){}//这里的impl就是个BpBinder对象,和binder扯上关系
....h文件中定义的虚函数实现
}
5)在IMyService.cpp加入宏定义IMPLEMENT_META_INTERFACE(MyService,”***”)//这个宏和上个宏,new一个BpMyService类,并传个BpBinder进去。
6)在IMyService.cpp中实现BnMyService类的onTrasact()接收BpMyService的onTrasact经过IPCThreadState发过来的数据,
7)建立真正的本地接口实现类MyService类头文件,继承BnMyService,定义功能函数和初始化函数instantiate()
8)在本地实现类MyService.cpp的instatiate()中把这个服务注册到ServiceManager服务管家
9)在服务的进程入口函数里调用服务的instantiate;这以后服务端的binder就搭建完成了
10)客户端获取服务代理对象
客户端进程想要和服务端通信,首先须要获取ServiceManager的代理对象,而后查找服务,返回该服务代理对象的引用,此代理对象中包含一个指向查找的服务的handle句柄
11)客户端调用服务端函数
客户端进程调用MyService的接口函数,调用会传递给包含了服务对象handler的代理对象的BpBinder,写入binder内核驱动,binder驱动知道数据传递到的对象,因而将数据传递给该进程;服务端进程从binder驱动中读取数据,而后处理远程调用,而后发送reply数据给binder驱动,binder驱动将reply传递给客户端进程,客户端进程从binder驱动中读取数据并最终获取到reply,从而完成进程通讯。