Android之BInder分析
MediaService的诞生:
nt main(int argc, char** argv) { //FT,就这么简单?? //获得一个ProcessState实例 sp<ProcessState> proc(ProcessState::self());//这里获得一个Process的实例,因为这个实例是单例结构的因此也就是说PorcessState在整个MediaServer这个ServiceManager真个进程里是唯一的共享的 //得到一个ServiceManager对象 sp<IServiceManager> sm = defaultServiceManager();//这里实际上就是使用BINDER_SET_CONTEXT_MGR命令把自己注册成ServiceManger,当Bunder驱动手动这个命令后,就会在驱动内存中实例化一个Binder实体就是BpBInder,事实上每个ServiceManger在刚执行的时候都会向驱动注册ServiceManger MediaPlayerService::instantiate();//初始化MediaPlayerService服务 //对于在代码里就向MangerService注册好的Service,自然会在ServiceManger差不多准备好的时候就实例化(其实也是实例化BnBinder),这个实例化后就会放入一个查询表中,同样当服务器端调用addService的时候,Binder驱动也会实例化一个BnBinder并把这个Bnbinder的名字和引用一起放在查询表中。这样Cilent端就能够根据getService来获得服务器的引用,因为在执行getService的时候就是在根据名字查询这个表。 ProcessState::self()->startThreadPool();//看名字,启动Process的线程池? //ProcessState是操作/dev/binder设备的,因为ServiceManger会为很多的Service和Cilent服务就会很多次的操作/dev/binder设备,所以启动线程池来访问binder设备也能加快访问速度(也说明binder设别是支持多线程的)
IPCThreadState::self()->joinThreadPool();//将自己加入到刚才的线程池? //Service接受客户端的数据并不是直接接受的而是通过IPCThreadState来调用BnBinder的transact方法,由transact方法来调用Service的onTransact方法实现远程功能的调用的。
//事实上ServiceMangerAndroid基于BInder C/S结构的守护进程,就是这是一直在监听客户端请求的一端,并能接受的客户端的请求后立即打开一个线程IPCThreadState来为客户端服务,ServieManger打开IPCThreadState后会根据客户端传过来的服务的名字(java端的调用形式为getSystemService(Context.LAYOUT_INFLATER_SERVICE))来查询对应的BnBInder(就是Service在这里注册BInder),然后调用BnBinder的onTranstact来实现。
}
ProcessState:
sp<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() : 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)了 } ... }
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。