您的位置:首页 > 移动开发 > Android开发

android binder机制之--(我是Server Porxy)

2011-07-24 20:47 288 查看

服务代理对象

上一篇androidbinder机制之--(我是ServiceManager)我们学习了ServiceManager(服务管家)在AndroidBinder中的作用——服务(Service)注册,服务(Service)查询和获取等功能。我们知道ServiceManager既是服务的管理对象,又是一个系统级的服务server(通过向驱动发送设置命令,使自己成为服务管家),它用来管理系统服务,也用于向客户端体统服务。那么ServiceManager的客户端(包括我们通常所说的其它系统服务和系统服务的客户端)如何同它进行通讯呢?客户端不可能凭空发送请求吧!那么在android系统中的binder肯定有实现客户端和服务端联系的机制。本文我们一起学习服务(Service)在客户端中的代理机制,服务代理对象就是服务端和客户端的这个联络员。在详细介绍服务代理之前,让我们先来了解一下服务代理在应用中的模型。(一)服务代理应用模型下面是客户端(这里的客户端是泛指请求服务的一方,自然有时候也包括SystemServer,比如当SystemServer向ServiceManager请求添加服务的时候)通过服务代理,向服务器端请求服务的模型:(1)首先客户端向Servicemanager查找相应的Service。这在前一篇文中有比较详细的介绍,这里不做赘述。(2)Android系统的binder机制将会为客户端进程中创建一个Service代理,这个创建过程是本文的重点,下面会详细介绍。(3)客户端视角只有Service代理,他所有对Service的请求都发往Service代理,然后由Service代理把用户请求转发给Service本身。(4)Service处理完成之后,把结果返回给Service代理,Service代理负责把处理结果返回给客户端。注意客户端对Service代理的调用都是同步调用(调用挂起,直到调用返回为止),这样客户端视角来看调用远端Service的服务和调用本地的函数没有任何区别。这就是我之前说的Binder机制的一个特点—线程迁移,这使得一个线程就像进入另一个线程执行并待会执行结果。(二)MediaService要想说明白服务代理的创建过程,还真不是那么容易的,最好的办法就是参照android中的源码,一步步走下去,这里我们还是选择MediaService的应用为例吧(看过一些资料也是以MS为例介绍的)。MediaService是android系统中的一个应用程序,和其他普通的应用程序没什么不同,源码如下:framework\base\Media\MediaServer\Main_mediaserver.cpp
intmain(intargc,char**argv)
{
sp<ProcessState>proc(ProcessState::self());
sp<IServiceManager>sm=defaultServiceManager();
LOGI("ServiceManager:%p",sm.get());
AudioFlinger::instantiate();
MediaPlayerService::instantiate();
CameraService::instantiate();
AudioPolicyService::instantiate();
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
}
怎么样?看到这个文件的代码是不是很迷惑啊!那么多陌生的东东,怎么理解啊!那么多的难关,那么厚的面纱,看来,要想见到服务代理的创建,还得过五关斩六将啊!下面我们就来层层剥开她神秘的面纱。

(1)ProcessState

在Android系统中任何进程,要想使用Binder机制,必须要创建一个ProcessState对象和IPCThreadState对象(不要急,这个对象我们将在后面介绍)。我们知道,一个客户端进程可能有多个Service的服务,这样就会创建多个Service代理(BpBinder对象,当然上面还会有封装的),那么这个进程就需要一个东东来管理这些服务代理。ProcessState就是这么个东东,它的作用就是维护当前进程中所有Service代理。ProcessState是一个singleton类型(关于这个类型,你可以查阅相关资料),一个进程只能创建一个他的对象。客户端进程中的ProcessState对象将会负责维护这些Service代理。那既然这样,Service代理是不是就是这个ProcessState创建的呢?呵呵,你猜对了,Service代理正是在这里被创建的,不过我可没打算现在就来分析服务代理的创建过程,你的一步一步脚踏实地地才能走向“光明”哦!上面的main函数中的第一句是什么?不就是这个ProcessState嘛,这里我们暂且记住一点,她就是一个管理服务代理的对象就好。先来看看她的创建过程,那就看看她的构造函数,咦,怎会回事?这个构造函数是私有成员那!
private:
ProcessState();
嗯,你没有看错,它的确是被声明成私有成员了,那就意味着在类的外部无法直接通过其构造函数,生成自己的一个对象,所以上面Main函数里面用了另一个公有成员函数ProcessState::self(),来调用其构造函数,生成ProcessState对象:
sp<ProcessState>ProcessState::self()
{
if(gProcess!=NULL)returngProcess;//如果已经创建了,//则直接返回这个全局的ProcessState对象
AutoMutex_l(gProcessMutex);
//如果第一次创建,调用其构造函数
if(gProcess==NULL)gProcess=newProcessState;
returngProcess;
}
还记得Main函数中的第一句:
sp<ProcessState>proc(ProcessState::self());
不是说不能在外部直接调用其构造函数的吗?其实这也不是我们讨论的重点,不过既然说了,就解释一下吧。熟悉C++的朋友应该都知道,当你定义的类中,没有显示定义一个复制构造函数的话,系统会帮你添加一个默认的复制构造函数,上面的就是调用这个复制构造函数。
ProcessState::ProcessState()定义如下:
ProcessState::ProcessState()
:mDriverFD(open_driver())/*太高强了,竟然在初始化列表中,直接调用函数,初始化成员变量,真是不容易看到啊*/
,mVMStart(MAP_FAILED)
,mManagesContexts(false)
,mBinderContextCheckFunc(NULL)
,mBinderContextUserData(NULL)
,mThreadPoolStarted(false)
,mThreadPoolSeq(1)
{
……
mVMStart=mmap(0,BINDER_VM_SIZE,PROT_READ,MAP_PRIVATE|MAP_NORESERVE,mDriverFD,0);//映射内存
……
}
这样就生成了一个ProcessState对象proc,用来管理本进程中所有的服务代理,当程序运行结束,proc会自动delete内部的内容,自动释放了先前分配的资源。这里ProcessState对象打开了/dev/binder设备,并保留了文件描述符,那么打开设备文件,自然是要用它进行通讯了,不过在ProcessState中你还真的很难找到,使用这个文件描述符进行通讯的代码。那么它在什么地方使用呢?我们会在后面介绍IPCThreadState时候在有说明。

(2)defaultServiceManager()

……
sp<IServiceManager>sm=defaultServiceManager();
这里生成了一个IserviceManager的对象sm,IserviceManager是什么?还记得上一篇文中的内容吧,serviceManager是服务管家,它负责系统服务的管理。你当然不会简单的认为有了serviceManager这个程序就万事OK了,这个守护进程做这么伟大的事,怎么可能孤军奋战,每一个成功的男人背后都有一个支持他的女人,这是谁说的,不记得了,呵呵!serviceManager也不例外,IserviceManager就提供了这样的一个机制,给了serviceManager管理服务的能力。那么这个sm究竟什么呢?说的明白点,上面那行代码就是生成了一个服务代理啦!不要惊奇,MS进程就是通过这个代理对象sm和ServiceManager通讯的,下面我们就来重点分析这个IserviceManager对象sm的创建过程。Frameworks\base\libs\binder\IserviceManager.cpp
p<IServiceManager>defaultServiceManager()
{
if(gDefaultServiceManager!=NULL)
returngDefaultServiceManager;//如果已经创建过,//直接返回
{
AutoMutex_l(gDefaultServiceManagerLock);
if(gDefaultServiceManager==NULL){
gDefaultServiceManager=interface_cast<IServiceManager>(ProcessState::self()->getContextObject(NULL));//创建代理对象
}
}
returngDefaultServiceManager;
}
这个函数中调用了下面的语句:gDefaultServiceManager=interface_cast<IServiceManager>(ProcessState::self()->getContextObject(NULL));//创建代理对象这是创建代理对象的地方,这句代码比较复杂一些,先来看看它的参数吧,ProcessState::self()我们现在已经很熟悉了,getContextObject()函数是干什么的:
sp<IBinder>ProcessState::getContextObject(constsp<IBinder>&caller)
{
if(supportsProcesses()){
/*根据参数句柄,创建一个代理对象,这里传的参数是0,记住这一点,在后面我们会解释*/
returngetStrongProxyForHandle(0);
}else{
returngetContextObject(String16("default"),caller);
}
}
这个getStrongProxyForHandle(int32_thandle)函数才是真正创建服务代理的地方,上面都是对其的封装罢了,看看这段代码:
sp<IBinder>ProcessState::getStrongProxyForHandle(int32_thandle)
{
sp<IBinder>result;
AutoMutex_l(mLock);
handle_entry*e=lookupHandleLocked(handle);/*我们之前说过ProcessState维护了该进程的一个服务代理对象的列表,这里就是根据handle句柄,在当前进程的服务代理链表中查找指定的服务代理对象,并返回一个handle_entry指针*/
if(e!=NULL){
IBinder*b=e->binder;
if(b==NULL||!e->refs->attemptIncWeak(this)){
b=newBpBinder(handle);/*看这里,服务代理就是在这被创建的,对,没错,BpBinder才是真正的服务代理,在上层生成的BpIServiceMananger对象是对她的封装,后面再做介绍*/
e->binder=b;
if(b)e->refs=b->getWeakRefs();//增加引用计数
result=b;
}else{
result.force_set(b);
e->refs->decWeak(this);
}
}
returnresult;
}
当前进程首先调用lookupHandleLocked函数去查看当前进程维护的Service代理对象的列表,该待创建Service代理对象是否已经在当前进程中创建,如果已经创建过了,则直接返回其引用就可以了。否则将会在Service代理对象的列表增加相应的位置,保存将要创建的代理对象。lookupHandleLocked的源码这里就不贴出来了,自己查阅吧!如果Service代理对象已经创建过了,直接增加引用计数就行了。若没有创建过,则需要创建一个新的Service代理对象。下面是BpBinder的构造函数:
BpBinder::BpBinder(int32_thandle)
:mHandle(handle)
,mAlive(1)
,mObitsSent(0)
,mObituaries(NULL)
{
LOGV("CreatingBpBinder%phandle%d\n",this,mHandle);
extendObjectLifetime(OBJECT_LIFETIME_WEAK);
IPCThreadState::self()->incWeakHandle(handle);
}
注意:上面创建服务代理对象时,传递的是handle,handle是一个表示符,用来标志不同的服务类型,这里的handle其实是0,上面已经有所说明,可以回头看看。Binder机制中,binder驱动每个服务维护一个服务句柄(这是Windows中的概念),上层创建服务代理对象时,传入一个唯一标志服务句柄handle,就可以获得这个特定服务句柄的代理对象。0号服务句柄就是ServiceMananger服务的,这是著名句柄,众所周知的。这里多少两句,我们刚才应该看到了,代码生产了一个BpBinder对象,并赋给了sp<IBinder>指针,说明BpBinder是Ibinder的一个继承类。Ibinder类是android系统对binder机制的一个抽象定义,其实就是一个抽象类,所有要实现binder机制的客户,服务端都要继承这个抽象类。这时程序又返回到了这里:gDefaultServiceManager=interface_cast<IServiceManager>(ProcessState::self()->getContextObject(NULL));//创建代理对象这个调用ProcessState::self()->getContextObject(NULL)返回的是sp<IBinder>类型,而gDefaultServiceManager是一个sp<IServiceManager>对象,这两者有嘛关系啊,为何能够转换呢?先不管这些,先来看看这个interface_cast<XXX>如何定义的吧!Framework\base\include\binder\Iiterface.h
template<typenameINTERFACE>
inlinesp<INTERFACE>interface_cast(constsp<IBinder>&obj)
{
returnINTERFACE::asInterface(obj);
}
这是个模版类,C++特有的东东,刚才的我们看到的是用IserviceManager来对模版进行实例化的,那我们还原一下代码:
template<typenameIserviceManager>
inlinesp<IserviceManager>interface_cast(constsp<IBinder>&obj)
{
returnIserviceManager::asInterface(obj);
}
那么这个IserviceManager::asInterface()在哪儿呢?我找遍源码也没发现它定义的地方,后来发现不是那么回事,要想理清这层关系还要从IserviceManager类说起,下面是它的定义:Framework\base\include\binder\IserviceManager.h
classIServiceManager:publicIInterface
{
public:
DECLARE_META_INTERFACE(ServiceManager);
……
virtualstatus_taddService(constString16&name,
constsp<IBinder>&service)=0;
……
};
这个类继承了IIterface类,并出现一个貌似宏的东东DECLARE_META_INTERFACE(ServiceManager);这是什么玩意呢?不太喜欢这个东东,所以一开始看代码时就没太注意这东西,可后来才发现这是类型转换的关键所在,看看定义:Framework\base\include\binder\Iiterface.h
#defineDECLARE_META_INTERFACE(INTERFACE)\
staticconstString16descriptor;\
staticsp<I##INTERFACE>asInterface(constsp<IBinder>&obj);\
virtualconstString16&getInterfaceDescriptor()const;\
I##INTERFACE();\
virtual~I##INTERFACE();\
这里可没有注释啊,那些“\”玩意都是控制换行连接的,这个定义一大堆的,都什么玩意,看的头痛,咱也不管它是什么,我们先来个顺藤摸瓜,既然上面IserviceManager类定义时,传递了一个ServiceManager参数,那就给他兑换出来看看得了,我把“\”去掉,就当是一个函数了,方便观察。
#defineDECLARE_META_INTERFACE(serviceManager)
staticconstString16descriptor;
staticsp<IserviceManager>asInterface(constsp<IBinder>&obj);
virtualconstString16&getInterfaceDescriptor()const;
IserviceManager();
virtual~IserviceManager();
呵呵,这下就一目了然了吧,不就是声明了一个字符串描述符和一个返回描述符的接口函数,还有构造和析构函数嘛!当然,这里出现了我们想要的东西asInterface()的定义,那这样我们上面的函数调用就有着落啦!嗯,现在是看看它定义的时候了!既然它声明这么横空,那定义怎么着也得打扮一下吧!瞧瞧,在IserviceManager.cpp文件中有这么一句代码:
IMPLEMENT_META_INTERFACE(ServiceManager,"android.os.IServiceManager");
真是双胞胎啊,长的那么像,看看这个孪生胞弟:
#defineIMPLEMENT_META_INTERFACE(INTERFACE,NAME)\
constString16I##INTERFACE::descriptor(NAME);\
constString16&I##INTERFACE::getInterfaceDescriptor()const{\
returnI##INTERFACE::descriptor;\
}\
sp<I##INTERFACE>I##INTERFACE::asInterface(constsp<IBinder>&obj)\
{\
sp<I##INTERFACE>intr;\
if(obj!=NULL){\
intr=static_cast<I##INTERFACE*>(\
obj->queryLocalInterface(\
I##INTERFACE::descriptor).get());\
if(intr==NULL){\
intr=newBp##INTERFACE(obj);\
}\
}\
returnintr;\
}\
I##INTERFACE::I##INTERFACE(){}\
I##INTERFACE::~I##INTERFACE(){}
还是看不下去了,先兑现先:
#defineIMPLEMENT_META_INTERFACE(serviceManager,"android.os.IServiceManager")
constString16IserviceManager::descriptor("android.os.IServiceManager");
constString16&IserviceManager::getInterfaceDescriptor()const{
returnIserviceManager::descriptor;
}
sp<IserviceManager>IserviceManager::asInterface(constsp<IBinder>&obj)
{
sp<IserviceManager>intr;
if(obj!=NULL){
intr=static_cast<IserviceManager*>(
obj->queryLocalInterface(IserviceManager::descriptor).get());
if(intr==NULL){
intr=newBpserviceManager(obj);/*原来在这里,通过Ibinder对象创建了一个BpserviceManager对象,然后返回给MS进程*/
}
}
returnintr;
}
I##INTERFACE::IserviceManager(){}
I##INTERFACE::~IserviceManager(){}
这下终于清楚了,最后就是将一个BpServiceManager对象返回给sm,那么你也看出来了,BpServiceManager是IserviceManager的一个继承类,而这个对象sm就是MS进程获得的ServiceManager服务的代理了,MS就可以通过sm这个代理对象发送添加服务等请求了。代码走到这里,服务代理对象的生成过程就结束了,总之一句话,defaultServiceManager()函数返回了一个ServiceManager的服务代理对象,提供给本进程的其他服务器端或客户端访问ServiceManager的接口。

(三)服务器端初始化

framework\base\Media\MediaServer\Main_mediaserver.cpp
intmain(intargc,char**argv)
{
……
AudioFlinger::instantiate();
MediaPlayerService::instantiate();
CameraService::instantiate();
AudioPolicyService::instantiate();
……
}
这四行代码就是android系统中,SM进程驱动的四个系统服务的初始化代码。每个服务都调用自己的instantiate()实例化函数,向ServiceManager注册自己,以为之前做过Camera模块,比较熟悉点,呵呵,所以我们以CameraServce::instantiate()为例来说明服务器端实例化的过程:Framework\base\camera\libcameraservice\cameraservice.cpp
voidCameraService::instantiate(){
defaultServiceManager()->addService(
String16("media.camera"),newCameraService());
}
其实就是这么简单,首先创建一个自己的实例,然后调用defaultServiceManager()函数,获得ServiceManager的服务代理对象,再通过这个代理对象调用添加服务函数,将自己注册到服务管理器,这个过程中的每一步,前面我们都已经分析过了,可以回头看看。其他的服务实例化过程和这个过程相同。

(四)ThreadState::startThreadPool()

VoidMain()
{
……
……
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
}
上面的代码已经说过了,这里就不列出来了,当MS执行到这里时,本进程完成了如下工作:(1)创建了ProcessState对象,用来管理本进程中获取的服务代理对象。注意:每一个进程只能创建一个该对象。(2)获取了ServiceManager的服务代理对象,可以通过这个对象和服务管家通讯了。(3)实例化了一些服务,并向服务管家成功添加了这些服务。既然服务端准备好了,就应该进入循环状态,以便接收来自客户端的请求,没错,那么,下面我们继续分析上面两句代码:
voidProcessState::startThreadPool()
{
AutoMutex_l(mLock);
if(!mThreadPoolStarted){
mThreadPoolStarted=true;
spawnPooledThread(true);
}
}
voidProcessState::spawnPooledThread(boolisMain)
{
if(mThreadPoolStarted){
……
sp<Thread>t=newPoolThread(isMain);
//创建线程池,然后跑起来
t->run(buf);
}
}
PoolThread继承自Thread,这里的PoolThread()构造函数,其实什么都没做,就连run()函数都没有重载,创建该对象后直接调用run()函数。真正的线程创建在其父类Thread的run()中被创建:
status_tThread::run(constchar*name,int32_tpriority,size_tstack)
{
……
if(mCanCallJava){
res=createThreadEtc(_threadLoop,
this,name,priority,stack,&mThread);
//这里创建了一个_threadLoop线程函数,这时候线程运行起来
}else{
res=androidCreateRawThreadEtc(_threadLoop,
this,name,priority,stack,&mThread);
}
……
}
intThread::_threadLoop(void*user)
{
Thread*constself=static_cast<Thread*>(user);
do{
if(first){
first=false;
self->mStatus=self->readyToRun();
……
}else{
result=self->threadLoop();//调用PoolThread的threadLoop()
}
……
}while(strong!=0);
return0;
}
Framework\base\libs\binder\ProcessThread.cpp
virtualboolthreadLoop()
{
IPCThreadState::self()->joinThreadPool(mIsMain);
returnfalse;
}
到了这里,发现很奇怪啊,也是调用的IPCThreadState::joinThreadPool()函数,好吧,既然两句都是调用这个函数,而且这里都再次引入了一个不可忽视的对象IPCThreadState,下面先来了解一下什么是IPCThreadState,然后在分析这个joinThreadPoll()函数。

(五)IPCThreadState

前面我们有提过,在ProcessState中打开了一个binder设备文件,并返回了一个文件描述符,在ProcessState中并没有使用这个文件描述符的地方,那么这个文件描述符到底被谁使用了呢?对,就是IPCThreadState对象。IPCThreadState也是一个singleton的类型,一个进程中也只能有一个这样的对象。它在android的binder机制中扮演什么样的角色呢?到了这里,你也可能已经猜到了,IPCThreadState主要负责信息的传递,所有要到达binder驱动和驱动中出来的信息,都要由IPCThreadState来传递。IPCThreadState有一个传输函数transact():
status_tIPCThreadState::transact(int32_thandle,
uint32_tcode,constParcel&data,
Parcel*reply,uint32_tflags)
{
……
if((flags&TF_ONE_WAY)==0){
if(reply){
err=waitForResponse(reply);
}else{
ParcelfakeReply;
err=waitForResponse(&fakeReply);
}
}else{
err=waitForResponse(NULL,NULL);
}
returnerr;
}
status_tIPCThreadState::waitForResponse(Parcel*reply,status_t*acquireResult)
{
int32_tcmd;
int32_terr;
while(1){
if((err=talkWithDriver())<NO_ERROR)break;
err=mIn.errorCheck();
cmd=mIn.readInt32();
switch(cmd){
caseBR_TRANSACTION_COMPLETE:
if(!reply&&!acquireResult)gotofinish;
break;
……
}
returnerr;
}
status_tIPCThreadState::talkWithDriver(booldoReceive)
{
……
do{
if(ioctl(mProcess->mDriverFD,BINDER_WRITE_READ,&bwr)>=0)
……
}while(err==-EINTR);
……
}
这里出现ioctl()函数了,这可是binder驱动的接口啊,下面就不再跟踪了,总之,上层的信息就是通过这个途径发送的binder驱动的。这样我们再来总结一下IPCThreadState对象的作用:(1)维护当前进程中所有对/dev/binder的读写。换句话说当前进程通过binder机制进行跨进程调用都是通过IPCThreadState对象来完成的。(2)IPCThreadState也可以理解成/dev/binder设备的封装,用户可以不直接通过ioctl来操作binder设备,都通过IPCThreadState对象来代理即可。说了半天,这里还是通过mDriverFD文件描述符,向binder设备文件写入数据。可是这个mDriverFD不是ProcessState的东东吗,怎么在这里被引用了呢?看看ProcessSate类定义就知道了。
private:
friendclassIPCThreadState;
哦,原来IPCThreadState是ProcessState的一个友元类,这样IPCThreadSate就可以名正言顺地使用mDriverFD了。好了,下面我们继续来分析joinThreadPool()函数吧!
voidIPCThreadState::joinThreadPool(boolisMain)
{
androidSetThreadSchedulingGroup(mMyThreadId,ANDROID_TGROUP_DEFAULT);
status_tresult;
do{
int32_tcmd;
result=talkWithDriver();
result=executeCommand(cmd);
}
}while(result!=-ECONNREFUSED&&result!=-EBADF);
mOut.writeInt32(BC_EXIT_LOOPER);
talkWithDriver(false);
}
看到了吧,这里是一个循环,循环调用talkWithDriver()从binder设备文件中读取信息,然后调用executeCommand()函数处理信息。这就是系统服务的循环体,不断重复地响应客户端的请求。不管是客户端进程和Service进程都是需要用IPCThreadState来和binder设备通讯的。那么现在我们从客户端和服务器端分别来总结一下IPCThreadState对象的作用。(1)如果是客户端进程,则通过服务代理BpBinder对象,调用transact函数,该函数作用就是把客户端的请求写入binder设备另一端的Service进程,详细的内容我们放在下一篇文章介绍。(2)作为Service进程,当他完成初始化工作之后,他们需要进入循环状态等待客户端的请求,Service进程调用它的IPCThreadState对象的joinThreadPool方法,开始轮询binder设备,等待客户端请求的到来。

(六)总结

本文中我们通过MS程序,分析了ServiceManager服务代理的创建过程,以及服务线程启动循环监听消息的过程,当然还有服务代理的概念,服务代理的管理对象ProcessState和消息传递对象IPCThreadState。后面我们会从客户端请求服务端的服务的视角,来分析binder机制在android系统中的实际应用。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: