🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
我们在main函数的开始处便碰见了ProcessState。由于每个进程只有一个ProcessState,所以它是独一无二的。它的调用方式如下面的代码所示: **Main_MediaServer.cpp** ~~~ //①获得一个ProcessState实例 sp<ProcessState> proc(ProcessState::self()); ~~~ 下面,来进一步分析这个独一无二的ProcessState。 1. 单例的ProcessState ProcessState的代码如下所示: **ProcessState.cpp** ~~~ sp<ProcessState> ProcessState::self() { //gProcess是在Static.cpp中定义的一个全局变量 //程序刚开始执行,gProcess一定为空 if(gProcess != NULL) return gProcess; AutoMutex_l(gProcessMutex); //创建一个ProcessState对象,并赋值给gProcess if(gProcess == NULL) gProcess = new ProcessState; return gProcess; } ~~~ self函数采用了单例模式,这很明确地告诉了我们一个信息:每个进程只有一个ProcessState对象。这一点,从它的命名中也可看出些端倪。 2. ProcessState的构造 再来看ProcessState的构造函数。这个函数非常重要,它悄悄地打开了Binder设备。代码如下所示: **ProcessState.cpp** ~~~ ProcessState::ProcessState() // Android的中有很多代码都是这么写的,稍不留神就容易忽略这里调用了一个很重要的函数 :mDriverFD(open_driver()) ,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 mmap的用法希望读者man一下,不过这个函数真正的实现和驱动有关系,而Binder驱动会分配一块 内存用来接收数据。 */ mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ,MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0); } ...... } ~~~ 3. 打开binder设备 open_driver的作用就是打开/dev/binder这个设备,它是android在内核中专门用于完成进程间通信而设置的一个虚拟设备,具体实现如下所示: **ProcessState.cpp** ~~~ static int open_driver() { int fd =open("/dev/binder", O_RDWR);//打开/dev/binder设备 if (fd>= 0) { ...... size_t maxThreads = 15; //通过ioctl方式告诉binder驱动,这个fd支持的最大线程数是15个 result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads); } return fd; ...... } ~~~ 至此,Process::self函数就分析完了。它到底干了什么呢?通过前面的分析,总结如下: - 打开/dev/binder设备,这就相当于与内核的Binder驱动有了交互的通道。 - 对返回的fd使用mmap,这样Binder驱动就会分配一块内存来接收数据。 - 由于ProcessState的惟一性,因此一个进程只打开设备一次。 分析完ProcessState,接下来将要分析第二个关键函数defaultServiceManager。