Android深入浅出之Binder机制 一 说明
Android系统最常见也是初学者最难搞明白的就是Binder了,很多很多的Service就是通过Binder机制来和客户端通讯交互的。所以搞明白Binder的话,在很大程度上就能理解程序运行的流程。
我们这里将以MediaService的例子来分析Binder的使用: ServiceManager,这是Android OS的整个服务的管理程序
MediaService,这个程序里边注册了提供媒体播放的服务程序MediaPlayerService,我们最后只分析这个
MediaPlayerClient,这个是与MediaPlayerService交互的客户端程序
下面先讲讲MediaService应用程序。 二 MediaService的诞生
MediaService是一个应用程序,虽然Android搞了七七八八的Java之类的东西,但是在本质上,它还是一个完整的linux操作系统,也还没有牛到什么应用程序都是JAVA写。所以,MS(MediaService)就是一个和普通的C++应用程序一样的东西。 MediaService底是个什么玩意儿!
int main(int argc, char** argv) {
//FT,就这么简单?? //获得一个ProcessState实例
sp
sp
MediaPlayerService::instantiate();//初始化MediaPlayerService服务 ProcessState::self()->startThreadPool();//看名字,启动Process的线程池? IPCThreadState::self()->joinThreadPool();//将自己加入到刚才的线程池? }
的源码文件在:
framework\\base\\Media\\MediaServer\\Main_mediaserver.cpp中。让我们看看到
其中,我们只分析MediaPlayerService。
这么多疑问,看来我们只有一个个函数深入分析了。不过,这里先简单介绍下sp这个东西。
sp,究竟是smart pointer还是strong pointer呢?其实我后来发现不用太关注这个,就把它当做一个普通的指针看待,即sp
好了,以后的分析中,sp
2.1 ProcessState
第一个调用的函数是ProcessState::self(),然后赋值给了proc变量,程序运行完,proc会自动delete内部的内容,所以就自动释放了先前分配的资源。 ProcessState位置在framework\\base\\libs\\binder\\ProcessState.cpp sp
if (gProcess != NULL) return gProcess;---->第一次进来肯定不走这儿 AutoMutex _l(gProcessMutex);--->锁保护
if (gProcess == NULL) gProcess = new ProcessState;--->创建一个ProcessState对象
return gProcess;--->看见没,这里返回的是指针,但是函数返回的是sp
//把sp
再来看看ProcessState构造函数 //这个构造函数看来很重要
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)了 } ... }
最讨厌这种在构造list中添加函数的写法了,常常疏忽某个变量的初始化是一个函数调用的结果。
open_driver,就是打开/dev/binder这个设备,这个是android在内核中搞的一个专门用于完成
进程间通讯而设置的一个虚拟的设备。BTW,说白了就是内核的提供的一个机制,这个和我们用socket加NET_LINK方式和内核通讯是一个道理。
static int open_driver() {
int fd = open(\打开/dev/binder if (fd >= 0) { ....
size_t maxThreads = 15;
//通过ioctl方式告诉内核,这个fd支持最大线程数是15个。 result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads); } return fd;
好了,到这里Process::self就分析完了,到底干什么了呢?
打开/dev/binder设备,这样的话就相当于和内核binder机制有了交互的通道 映射fd到内存,设备的fd传进去后,估计这块内存是和binder设备共享的
接下来,就到调用defaultServiceManager()地方了。
2.2 defaultServiceManager
defaultServiceManager
位
置
在
framework\\base\\libs\\binder\\IServiceManager.cpp中
sp
{
if (gDefaultServiceManager != NULL) return gDefaultServiceManager; //又是一个单例,设计模式中叫 singleton。 {
AutoMutex _l(gDefaultServiceManagerLock); if (gDefaultServiceManager == NULL) { //真正的gDefaultServiceManager是在这里创建的喔
gDefaultServiceManager = interface_cast
return gDefaultServiceManager; } -----》
gDefaultServiceManager = interface_cast
ProcessState::self,肯定返回的是刚才创建的gProcess,然后调用它的getContextObject,注意,传进去的是NULL,即0 //回到ProcessState类,
sp
if (supportsProcesses()) {//该函数根据打开设备是否成功来判断是否支持process, //在真机上肯定走这个
return getStrongProxyForHandle(0);//注意,这里传入0 } }
----》进入到getStrongProxyForHandle,函数名字怪怪的,经常严重阻碍大脑运转
//注意这个参数的命名,handle。搞过windows的应该比较熟悉这个名字,这是对
//资源的一种标示,其实说白了就是某个数据结构,保存在数组中,然后handle是它在这个数组中的索引。--->就是这么一个玩意儿
sp
相关推荐: