首页 / 操作系统 / Linux / Android深入浅出之Binder机制
一 说明Android系统最常见也是初学者最难搞明白的就是Binder了,很多很多的Service就是通过Binder机制来和客户端通讯交互的。所以搞明白Binder的话,在很大程度上就能理解程序运行的流程。我们这里将以MediaService的例子来分析Binder的使用:ServiceManager,这是Android OS的整个服务的管理程序MediaService,这个程序里边注册了提供媒体播放的服务程序MediaPlayerService,我们最后只分析这个MediaPlayerClient,这个是与MediaPlayerService交互的客户端程序下面先讲讲MediaService应用程序。二 MediaService的诞生MediaService是一个应用程序,虽然Android搞了七七八八的JAVA之类的东西,但是在本质上,它还是一个完整的Linux操作系统,也还没有牛到什么应用程序都是JAVA写。所以,MS(MediaService)就是一个和普通的C++应用程序一样的东西。MediaService的源码文件在:frameworkaseMediaMediaServerMain_mediaserver.cpp中。让我们看看到底是个什么玩意儿!int main(int argc, char** argv){//FT,就这么简单??//获得一个ProcessState实例sp<ProcessState> proc(ProcessState::self());//得到一个ServiceManager对象 sp<IServiceManager> sm = defaultServiceManager(); MediaPlayerService::instantiate();//初始化MediaPlayerService服务 ProcessState::self()->startThreadPool();//看名字,启动Process的线程池? IPCThreadState::self()->joinThreadPool();//将自己加入到刚才的线程池?}其中,我们只分析MediaPlayerService。这么多疑问,看来我们只有一个个函数深入分析了。不过,这里先简单介绍下sp这个东西。sp,究竟是smart pointer还是strong pointer呢?其实我后来发现不用太关注这个,就把它当做一个普通的指针看待,即sp======》IServiceManager*吧。sp是google搞出来的为了方便C/C++程序员管理指针的分配和释放的一套方法,类似JAVA的什么WeakReference之类的。我个人觉得,要是自己写程序的话,不用这个东西也成。好了,以后的分析中,sp就看成是XXX*就可以了。2.1 ProcessState第一个调用的函数是ProcessState::self(),然后赋值给了proc变量,程序运行完,proc会自动delete内部的内容,所以就自动释放了先前分配的资源。ProcessState位置在frameworkaselibsinderProcessState.cppsp<ProcessState> ProcessState::self(){ if (gProcess != NULL) return gProcess;---->第一次进来肯定不走这儿 AutoMutex _l(gProcessMutex);--->锁保护 if (gProcess == NULL) gProcess = new ProcessState;--->创建一个ProcessState对象return gProcess;--->看见没,这里返回的是指针,但是函数返回的是sp<xxx>,所以//把sp<xxx>看成是XXX*是可以的}再来看看ProcessState构造函数//这个构造函数看来很重要ProcessState::ProcessState() : mDriverFD(open_driver())----->Android很多代码都是这么写的,稍不留神就没看见这里调用了一个很重要的函数 , mVMStart(MAP_FAILED)//映射内存的起始地址 , mManagesContexts(false) , mBinderContextCheckFunc(NULL) , mBinderContextUserData(NULL) , mThreadPoolStarted(false) , mThreadPoolSeq(1){if (mDriverFD >= 0) {//BIDNER_VM_SIZE定义为(1*1024*1024) - (4096 *2) 1M-8K mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);//这个需要你自己去man mmap的用法了,不过大概意思就是//将fd映射为内存,这样内存的memcpy等操作就相当于write/read(fd)了 } ...}最讨厌这种在构造list中添加函数的写法了,常常疏忽某个变量的初始化是一个函数调用的结果。open_driver,就是打开/dev/binder这个设备,这个是android在内核中搞的一个专门用于完成进程间通讯而设置的一个虚拟的设备。BTW,说白了就是内核的提供的一个机制,这个和我们用socket加NET_LINK方式和内核通讯是一个道理。static int open_driver(){ int fd = open("/dev/binder", O_RDWR);//打开/dev/binder if (fd >= 0) { .... size_t maxThreads = 15; //通过ioctl方式告诉内核,这个fd支持最大线程数是15个。 result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads); } return fd;好了,到这里Process::self就分析完了,到底干什么了呢?打开/dev/binder设备,这样的话就相当于和内核binder机制有了交互的通道映射fd到内存,设备的fd传进去后,估计这块内存是和binder设备共享的接下来,就到调用defaultServiceManager()地方了。