Android中的binder机制

Binder使用client-server的通信方式:

一个进程作为server提供诸如视频/音频解码,视频捕获,地址本查询,网络连接等服务;多个进程作为clientserver发送服务请求,获得所需要的服务。

对于Binder而言,Binder可以看成是Server提供的实现某一个特定服务的访问接入点,Client可以通过这个‘地址’向server发送服务请求来是用该服务;对于Client而言,Binder可以看成是通向server的管道入口,要想和某一个server通信首先就要建立这个通道并且获得通道入口。

Binder是一个实体位于Server中的对象,该对象提供一套方法用以实现对服务的请求,就像类的成员函数,

Binder框架定义了四个角色:ServerClientServiceManager(以后简称SMgr)以及驱动。其中ServerClientSMgr运行于用户空间,驱动运行于内核空间。

Binder驱动虽然默默无闻,却是通信的核心。尽管名叫‘驱动’,实际上和硬件设备没有任何关系,只是实现方式和设备驱动程序是一样的:它工作于内核态,提供open()mmap()poll()ioctl()等标准文件操作,以字符驱动设备中的misc设备注册在设备目录/dev下,用户通过/dev/binder访问该它。驱动负责进程之间Binder通信的建立,Binder在进程之间的传递,Binder引用计数管理,数据包在进程之间的传递和交互等一系列底层支持。驱动和应用程序之间定义了一套接口协议,主要功能由ioctl()接口实现,不提供read()write()接口,因为ioctl()灵活方便,且能够一次调用实现先写后读以满足同步交互,而不必分别调用write()read()

SMgr的作用是将字符形式的Binder名字转化成Client中对该Binder的引用,使得Client能够通过Binder名字获得对ServerBinder实体的引用。





下面从MediaService的例子来分析Binder的使用:

1ServiceManager,这是AndroidOS 的整个服务的管理程序

2MediaService,这个程序里面注册了提供媒体播放的服务程序MediaPlayerService.

3MediaPlayerClient,这个是与MediaPlayerService交互的客户端程序。

首先是MediaService

frameworks/base/Media/MediaServer/Main_mediaserver.cpp中。

intmain(int argc, char** argv)

{

        //获得一个ProcessState实例

        sp<ProcessState>proc(ProcessState::self());

   //得到一个ServiceManager对象

sp<IServiceManager> sm = defaultServiceManager();

MediaPlayerService::instantiate();//初始化MediaPlayerService服务

ProcessState::self()->startThreadPool();//看名字,启动Process的线程池?

IPCThreadState::self()->joinThreadPool();//将自己加入到刚才的线程池?

}

一步一步看:

1ProcessState

第一个调用的是ProcessState::self(),然后负赋值给proc变量,程序运行完,proc会自动delete内部的内容,所以就自动释放了先前分配的资源。

frameworks/base/include/binder/ProcessState.cpp

sp<ProcessState>ProcessState::self()

{

if(gProcess != NULL) return gProcess;

AutoMutex_l(gProcessMutex);

if(gProcess == NULL) gProcess = new ProcessState;

returngProcess;

}

new的时候会调用ProcessState的构造函数,下面看看构造函数:

ProcessState::ProcessState() : mDriverFD(open_driver()) , mVMStart(MAP_FAILED)

,mManagesContexts(false) , mBinderContextCheckFunc(NULL)

,mBinderContextUserData(NULL) , mThreadPoolStarted(false) ,mThreadPoolSeq(1)

{

if(mDriverFD >= 0) {

//XXX Ideally, there should be a specific define for whether we

//have mmap (or whether we could possibly have the kernel module

//availabla).

#if!defined(HAVE_WIN32_IPC)

//mmap the binder, providing a chunk of virtual address space toreceive 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

}

LOG_ALWAYS_FATAL_IF(mDriverFD< 0, "Binder driver could not be opened. Terminating.");

}

在构造函数的初始化列表中第一个就是open_driver(),返回文件指针,这个文件指针在mVMStart= mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE,mDriverFD, 0);的时候使用,我们先看一下open_driver()函数,

staticint open_driver()

{

intfd = open("/dev/binder", O_RDWR);

if(fd >= 0) {

fcntl(fd,F_SETFD, FD_CLOEXEC);

intvers;

status_tresult = ioctl(fd, BINDER_VERSION, &vers);

if(result == -1) {

LOGE("Binderioctl to obtain version failed: %s", strerror(errno));

close(fd);

fd= -1;

}

if(result != 0 || vers != BINDER_CURRENT_PROTOCOL_VERSION) {

LOGE("Binderdriver protocol does not match user space protocol!");

close(fd);

fd= -1;

}

size_tmaxThreads = 15;

//通过ioctl告诉内核,这个fd所支持的最大线程数是15

result= ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads);

if(result == -1) {

LOGE("Binderioctl to set max threads failed: %s", strerror(errno));

}

}else {

LOGW("Opening'/dev/binder' failed: %s\n", strerror(errno));

}

returnfd;

}

到这里processState::self()就执行完了,它主要完成的工作有:

1、打开dev/binder设备,这样的话就相当于和内核binder机制有了交互的通道

2、映射fd到内存中,设备fd传进去之后,这块内存和binder设备共享了

2defaultServiceManager

所在的位置在frameworks/base/lib/binder/IServiceManager.c

sp<IServiceManager>defaultServiceManager()

{

if(gDefaultServiceManager != NULL) return gDefaultServiceManager;

{

AutoMutex_l(gDefaultServiceManagerLock);

if(gDefaultServiceManager == NULL) {

gDefaultServiceManager= interface_cast<IServiceManager>(

ProcessState::self()->getContextObject(NULL));

}

}

returngDefaultServiceManager;

}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值