Server进程和Client进程获取ServiceManager的远程接口
来源:互联网 发布:判断平年和闰年的java 编辑:程序博客网 时间:2024/05/22 22:40
上篇博客《ServiceManager如何成为Binder进程通信的守护进程》已经详细讲述了ServiceManager是如何成为守护进程,然而其作为守护进程是如何为Server进程和Client进程提供服务的,也即Server进程和Client进程如何获得ServiceManager的远程接口(代理对象)的呢?此时ServiceManager必然是作为Server的,其与普通的Server进程是不一样的;对于普通的Server来说,Client如果想要获得Server的远程接口,必须通过ServiceManager远程接口提供的getService接口来获得,这本身就是一个Binder机制进行进程间通信的过程;然而对于ServiceManager这个Server来说,Client如果想得到ServiceManager远程接口,不必通过进程间通信机制来获得,因为ServiceManager远程接口是一个binder引用,它的句柄一定是0;
一、ServiceManager远程接口关系图
1)ServiceManager远程接口对象类型为BpServiceManager,它用来描述一个实现IServiceManager接口的Client组件。
2)IServiceManager接口定义4个成员函数getService,checkService,addService和listService;其中,getService和checkService是用来获取Service组件的代理对象的。addService用来注册Service组件的;listService用来获取注册在ServiceManager中的Service组件的列表。
3)对一般的Service组件来说,Client进程首先要通过Binder驱动程序来获取它的一个句柄值,然后通过这个句柄创建一个Binder代理对象,最后将这个Binder代理对象封装成一个实现特定接口的代理对象。由于ServiceManager的句柄值为0,因此获取它的代理对象不需要跟Binder驱动程序进程交互。
4)通过函数defaultServiceManager来获得一个ServiceManager代理对象。
二、defaultServiceManager
函数实现位于frameworks/base/libs/binder/IServiceManager.cpp文件中:
sp<IServiceManager> defaultServiceManager(){//又是一个单例模式,Singleton if (gDefaultServiceManager != NULL) return gDefaultServiceManager; { AutoMutex _l(gDefaultServiceManagerLock); if (gDefaultServiceManager == NULL) {//真正的gDefaultServiceManager在这里创建 gDefaultServiceManager = <span style="color:#ff0000;">interface_cast</span><IServiceManager>( <span style="color:#ff0000;">ProcessState::self()</span>-><span style="color:#ff0000;">getContextObject(NULL))</span>;//从这里可以看到调用的ProcessState的getContextObject来创建,然后interface_cast<IServiceManager>利用BpBinder对象作为参数新建一个BpServiceManager对象 } } return gDefaultServiceManager;}
sp<ProcessState> 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;}
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. }}
位于frameworks/base/libs/binder/ProcessState.cpp文件中:
sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& caller){/*caller的值为0,而且该函数返回的是一个IBinder。supportsProcesses()是查看设备是否支持打开设备来判断它是否支持process**/ if (supportsProcesses()) {//真实的设备肯定支持,所以会调用下面的函数来得到IBinder return getStrongProxyForHandle(0); } else { return getContextObject(String16("default"), caller); }}
sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle){ sp<IBinder> 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. <span style="color:#ff0000;">b = new BpBinder(handle); //创建一个BpBinder</span> 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值为02.3 调用模板函数interface_cast<IServiceManager>将Binder代理对象封装为ServiceManager代理对象
template<typename INTERFACE>inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj){ return INTERFACE::asInterface(obj);}这只是一个模板方法,所以defaultServiceManager中的interface_cast<IServiceManager>可等价于:
inline sp<IServiceManager> interface_cast(const sp<IBinder>& obj){ return IServiceManager::asInterface(obj);}三、Server和Client进程拿到ServiceManager远程接口后,如何使用?
- Server进程和Client进程获取ServiceManager的远程接口
- 2.3 Android进程间通信(IPC)----Server和Client获得Service Manager远程接口
- ServiceManager守护进程的注册
- ServiceManager远程代理的获取
- Binder进程间通信机制的Client进程和Server进程的通信过程
- FregServer进程,获取ServiceManager代理对象
- Android系统进程间通信(IPC)机制Binder中的Client获得Server远程接口过程源代码分析
- [Binder.4] Android系统进程间通信(IPC)机制Binder中的Client获得Server远程接口过程源代码分析
- Android系统进程间通信(IPC)机制Binder中的Client获得Server远程接口过程源代码分析
- Android系统进程间通信(IPC)机制Binder中的Client获得Server远程接口过程源代码分析
- Android系统进程间通信(IPC)机制Binder中的Client获得Server远程接口过程源代码分析
- Android系统进程间通信(IPC)机制Binder中的Client获得Server远程接口过程源代码分析
- Android系统进程间通信(IPC)机制Binder中的Client获得Server远程接口过程源代码分析
- Android系统进程间通信(IPC)机制Binder中的Client获得Server远程接口过程源代码分析
- Android系统进程间通信(IPC)机制Binder中的Client获得Server远程接口过程源代码分析
- Android系统进程间通信(IPC)机制Binder中的Client获得Server远程接口过程源代码分析
- Android系统进程间通信(IPC)机制Binder中的Client获得Server远程接口过程源代码分析
- Android系统进程间通信(IPC)机制Binder中的Client获得Server远程接口过程源代码分析
- 学校自己挂的题目。。。我也不知道是哪里的。。。
- bash :- : no such file or directory
- 第十周项目一 阅读下面的定义,请说出在测试函数中不同情况的调用产生的结果(5 e)
- Problem E
- Linux下调试与性能分析工具的总结
- Server进程和Client进程获取ServiceManager的远程接口
- hdu4283(区间dp)
- Ajax 完整教程 (转)
- cocos2dx的CCLabelTTF类使用不同的TTF字库时字体没有变化的问题
- VB.NET版机房收费系统之限制textbox输入
- 孤儿进程与僵尸进程
- Boolean和boolean的区别
- 堆排序
- 渐近记号