本文主要是介绍Android Binder进程间通信-ServiceManager代理对象的获取过程,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
文章来源:http://www.itnose.net/detail/6043249.html
更多文章:http://www.itnose.net/type/85.html
一、测试代码:
~/Android/external/binder/server
----FregServer.cpp
~/Android/external/binder/common
----IFregService.cpp
----IFregService.h
~/Android/external/binder/client
----FregClient.cpp
Binder库(libbinder)代码:
~/Android/frameworks/base/libs/binder
----BpBinder.cpp
----Parcel.cpp
----ProcessState.cpp
----Binder.cpp
----IInterface.cpp
----IPCThreadState.cpp
----IServiceManager.cpp
----Static.cpp
~/Android/frameworks/base/include/binder
----Binder.h
----BpBinder.h
----IInterface.h
----IPCThreadState.h
----IServiceManager.h
----IBinder.h
----Parcel.h
----ProcessState.h
驱动层代码:
~/Android//kernel/goldfish/drivers/staging/android
----binder.c
----binder.h
二、源码分析
1、程序首先开始从Service进程FregServer.cpp的main函数开始执行
~/Android/external/binder/server
----FregServer.cpp
class FregService : public BnFregService {........... public:static void instantiate(){defaultServiceManager()->addService(String16(FREG_SERVICE), new FregService());}........... };int main(int argc, char** argv) {FregService::instantiate();ProcessState::self()->startThreadPool();IPCThreadState::self()->joinThreadPool();return 0; }main函数首先调用静态方法instantiate,在instantiate中调用了defaultServiceManager(), defaultServiceManager()函数实现如下:
~/Android/frameworks/base/libs/binder
----IServiceManager.cpp
sp<IServiceManager> defaultServiceManager() {if (gDefaultServiceManager != NULL) return gDefaultServiceManager;//如果已经创建了代理对象,那么就直接返回{AutoMutex _l(gDefaultServiceManagerLock);//使用锁,来实现单例模式if (gDefaultServiceManager == NULL) {gDefaultServiceManager = interface_cast<IServiceManager>(//分三步获取Service Manager代理对象ProcessState::self()->getContextObject(NULL));}}return gDefaultServiceManager; }其中gDefaultServiceManagerLock,gDefaultServiceManager都定义在Static.cpp中。
~/Android/frameworks/base/libs/binder
----Static.cpp
Mutex gDefaultServiceManagerLock; //锁 sp<IServiceManager> gDefaultServiceManager; //IServiceManager的强指针全局变量 gDefaultServiceManager是一个类型为IServiceManager的强指针,它指向进程内的一个BpServiceManager对象,即Service Manager代理对象;而全局变量gDefaultServiceManagerLock是用来保证一个进程至多只有一个Service Manager代理对象。结合锁机制来保证对象在进程中的唯一性,这是单例设计模式的经典实现。
如果已经创建了代理对象,那么就直接返回。如果没有创建,那么分三步创建:
(1)、调用ProcessState类的静态成员函数self获取进程内的一个ProcessState对象。
(2)、调用前面获得的ProcessState对象的成员函数getContextObject创建一个Binder代理对象
(3)、调用模板函数interface_cast<IServiceManager>将前面获得的Binder代理对象封装成一个Service Manager代理对象。
2、调用ProcessState类的静态成员函数self获取进程内的一个ProcessState对象
~/Android/frameworks/base/libs/binder
----ProcessState.cpp
sp<ProcessState> ProcessState::self() {if (gProcess != NULL) return gProcess;//如果已经创建了,就直接返回AutoMutex _l(gProcessMutex);if (gProcess == NULL) gProcess = new ProcessState;//创建ProcessState对象return gProcess; }其中gProcess,gProcessMutex都位于Static.cpp中
Mutex gProcessMutex; sp<ProcessState> gProcess;全局变量gProcess是一个类型为ProcessState的强指针,它指向进程内的一个ProcessState对象;而全局变量gProcessMutex是一个互斥锁,是用来保证一个进程至多只有一个ProcessState对象的,同样是一个单例模式。
首次进入,故创建ProcessState对象。
~/Android/frameworks/base/libs/binder
----ProcessState.cpp
ProcessState::ProcessState(): mDriverFD(open_driver()), mVMStart(MAP_FAILED)..... {if (mDriverFD >= 0) {...........// 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);........... }在初始化构造函数中调用了open_driver方法。
~/Android/frameworks/base/libs/binder
----ProcessState.cpp
static int open_driver() {if (gSingleProcess) {return -1;}int fd = open("/dev/binder", O_RDWR);//又一个进程打开了设备文件,binder_procs又多了一个进程的结构体if (fd >= 0) {fcntl(fd, F_SETFD, FD_CLOEXEC);int vers; #if defined(HAVE_ANDROID_OS)status_t result = ioctl(fd, BINDER_VERSION, &vers); #elsestatus_t result = -1;errno = EPERM; #endifif (result == -1) {LOGE("Binder ioctl to obtain version failed: %s", strerror(errno));close(fd);fd = -1;}if (result != 0 || vers != BINDER_CURRENT_PROTOCOL_VERSION) {LOGE("Binder driver protocol does not match user space protocol!");close(fd);fd = -1;} #if defined(HAVE_ANDROID_OS)size_t maxThreads = 15;result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads);if (result == -1) {LOGE("Binder ioctl to set max threads failed: %s", strerror(errno));} #endif} else {LOGW("Opening '/dev/binder' failed: %s\n", strerror(errno));}return fd; }open_driver首先调用了open打开设备文件,在http://blog.csdn.net/jltxgcy/article/details/25797011这盘文章中已经讲解了驱动层的binder_open所做的事。然后的调用ioctl传入BINDER_VERSION参数来获取vers。最后调用ioctl传入BINDER_SET_MAX_THREADS参数来设备该进程所支持的最大线程数。
在初始化列表中调用mmap把设备文件/dev/binder映射到进程的地址空间,其实将/dev/binder映射到进程的地址空间实际上是请求Binder驱动程序为进程分配内核缓冲区。
3、调用前面获得的ProcessState对象的成员函数getContextObject创建一个Binder代理对象
~/Android/frameworks/base/libs/binder
----ProcessState.cpp
sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& caller) {if (supportsProcesses()) {return getStrongProxyForHandle(0);} else {return getContextObject(String16("default"), caller);} }
这篇关于Android Binder进程间通信-ServiceManager代理对象的获取过程的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!