函数实现位于frameworks/base/libs/binder/IServiceManager.cpp文件中:
sp defaultServiceManager(){ //又是一个单例模式,Singleton if (gDefaultServiceManager != NULL) return gDefaultServiceManager; { AutoMutex _l(gDefaultServiceManagerLock); if (gDefaultServiceManager == NULL) { //真正的gDefaultServiceManager在这里创建 gDefaultServiceManager = interface_cast( ProcessState::self()->getContextObject(NULL)); //从这里可以看到调用的ProcessState的getContextObject来创建,然后interface_cast利用BpBinder对象作为参数新建一个BpServiceManager对象 } } return gDefaultServiceManager;}
1)全局变量gDefaultServiceManager是一个类型为IServiceManager的强指针,指向进程内的一个BpServiceManager对象,即ServiceManager远程接口。
2)全局变量gDefaultServiceManagerLock是一个互斥锁,保证一个进程中至多只有一个ServiceManager代理对象。
3)重点:三次函数调用: 1)调用ProcessState类的静态成员函数self获取进程内一个ProcessState对象;2)调用ProcessState对象的成员函数getContextObject创建一个Binder代理对象;3)调用模板函数interface_cast将Binder代理对象封装成ServiceManager代理对象。
2.1 ProcessState::self成员函数
位于frameworks/base/libs/binder/ProcessState.cpp文件中:
sp ProcessState::self(){ //gProcess是在Static.app中定义的全局变量 //程序开始的时候。gProcess肯定为NULL if (gProcess != NULL) return gProcess; AutoMutex _l(gProcessMutex); //创建一个ProcessState对象,并赋给gProcess if (gProcess == NULL) gProcess = new ProcessState; return gProcess;}
1)全局变量gProcess是一个类型为ProcessState的强指针,执行进程内一个ProcessState对象;
2)gProcessMutex是一个互斥锁,用来保证进程内最多只有一个ProcessState对象。
3)重点:通过ProcessState构造函数—> 创建ProcessState对象
ProcessState::ProcessState() : mDriverFD(open_driver()) //open_driver打开Binder设备 , mVMStart(MAP_FAILED) //内存映射的起始地址 , mManagesContexts(false) , mBinderContextCheckFunc(NULL) , mBinderContextUserData(NULL) , mThreadPoolStarted(false) , mThreadPoolSeq(1){ if (mDriverFD >= 0) {#if !defined(HAVE_WIN32_IPC) // mmap the binder, providing a chunk of virtual address space to receive transactions. mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0); if (mVMStart == MAP_FAILED) { // sigh LOGE(“Using /dev/binder failed: unable to mmap transaction memory.\n”); close(mDriverFD); mDriverFD = -1; }#else mDriverFD = -1;#endif } if (mDriverFD < 0) { // Need to run without the driver, starting our own thread pool. }}
在ProcessState构造函数中:
1)首先调用open_driver打开设备/dev/binder,并且将得到的文件描述符保证在成员变量mDriverFD中。
2)调用mmap函数把设备文件/dev/binder映射到进程的地址空间,映射的地址空间大小为 BINDER_VM_SIZE:请求Binder驱动程序为进程分配内核缓冲区。
2.2 调用getContextObject创建一个Binder代理对象
位于frameworks/base/libs/binder/ProcessState.cpp文件中:
sp ProcessState::getContextObject(const sp& caller){ /* caller的值为0,而且该函数返回的是一个IBinder。 supportsProcesses()是查看设备是否支持打开设备来判断它是否支持process **/ if (supportsProcesses()) { //真实的设备肯定支持,所以会调用下面的函数来得到IBinder return getStrongProxyForHandle(0); } else { return getContextObject(String16(“default”), caller); }}
1)先通过supportsProcesses来检查系统是否支持Binder进程间通信机制;
2)然后调用getStrongProxyForHandler来创建一个Binder代理对象
sp ProcessState::getStrongProxyForHandle(int32_t handle){ sp result; AutoMutex _l(mLock); /* 根据索引查找对应的资源,如果lookupHandleLocked没有发现对应的资源,则会创建一个新的项并返回 / handle_entry e = lookupHandleLocked(handle); if (e != NULL) { // We need to create a new BpBinder if there isn’t currently one, OR we // are unable to acquire a weak reference on this current one. See comment // in getWeakProxyForHandle() for more info about this. IBinder* b = e->binder; if (b == NULL || !e->refs->attemptIncWeak(this)) { //对于新创建的资源项,它的binder为空,此时handle值为0. b = new BpBinder(handle); //创建一个BpBinder e->binder = b; //填充entry的内容 if (b) e->refs = b->getWeakRefs(); result = b; } else { // This little bit of nastyness is to allow us to add a primary // reference to the remote proxy when this team doesn’t have one // but another team is sending the handle to us. result.force_set(b); e->refs->decWeak(this); } } return result; //返回BpBinder(handler),handle值为0
2.3 调用模板函数interface_cast将Binder代理对象封装为ServiceManager代理对象
【附】相关架构及资料
源码、笔记、视频。高级UI、性能优化、架构师课程、NDK、混合式开发(ReactNative+Weex)微信小程序、Flutter全方面的Android进阶实践技术,和技术大牛一起讨论交流解决问题。
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门,即可获取!
g-CeaoDXGP-1715365326630)]
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门,即可获取!