服务代理对象
上一篇android binder机制之--(我是Service Manager)我们学习了Service Manager(服务管家)在Android Binder中的作用——服务(Service)注册,服务(Service)查询和获取等功能。
我们知道Service Manager既是服务的管理对象,又是一个系统级的服务server(通过向驱动发送设置命令,使自己成为服务管家),它用来管理系统服务,也用于向客户端体统服务。那么Service Manager的客户端(包括我们通常所说的其它系统服务和系统服务的客户端)如何同它进行通讯呢?客户端不可能凭空发送请求吧!那么在android系统中的binder肯定有实现客户端和服务端联系的机制。
本文我们一起学习服务(Service)在客户端中的代理机制,服务代理对象就是服务端和客户端的这个联络员。在详细介绍服务代理之前,让我们先来了解一下服务代理在应用中的模型。
(一)服务代理应用模型
下面是客户端(这里的客户端是泛指请求服务的一方,自然有时候也包括System Server,比如当System Server向Service Manager请求添加服务的时候)通过服务代理,向服务器端请求服务的模型:
(1)首先客户端向Service manager查找相应的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
int main(int argc, 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) return gProcess;//如果已经创建了,//则直接返回这个全局的ProcessState对象
AutoMutex _l(gProcessMutex);
//如果第一次创建,调用其构造函数
if (gProcess == NULL) gProcess = new ProcessState;
return gProcess;
}
还记得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设备,并保留了文件描述符,那么打开设备文件,自然是