Binder

好久没有写android相关的技术博客了,由于近期工作中需要做安卓项目,所以唤起了对安卓的重新学习激情。个人认为Binder是安卓的通信灵魂,所以准备从Binder开始研究安卓。

Binder机制中的4个组件Client, Server, Service Manager和Binder驱动关系图如下:

Binder_第1张图片

这个图还是比较清楚的能够看出4者之间的调用关系,相信有点安卓经验的朋友应该比较清晰,这里只做个感情的认识,不做进一步的讲解。不过还是要补充2点:

1.Binder驱动和Service Manager在安卓平台中已经实现,开发定制者只需要在用户空间实现自己的Client和Server。

2.Service Manager是个守护进程,用来管理Server,并向Client提供查询Server接口的能力。

下面从framework的角度去详细分析Binder的通信原理.

一. Service Manager是如何成为一个守护进程的?(即Service Manager是如何告知Binder驱动它是Binder机制的上下文管理者)

Service Manager的入口位于service_manager.c文件中的main函数:

[cpp]  view plain  copy
 
  1. int main(int argc, char **argv)  
  2. {  
  3.     struct binder_state *bs;  
  4.     void *svcmgr = BINDER_SERVICE_MANAGER;  
  5.   
  6.     bs = binder_open(128*1024);  
  7.   
  8.     if (binder_become_context_manager(bs)) {  
  9.         LOGE("cannot become context manager (%s)\n", strerror(errno));  
  10.         return -1;  
  11.     }  
  12.   
  13.     svcmgr_handle = svcmgr;  
  14.     binder_loop(bs, svcmgr_handler);  
  15.     return 0;  
  16. }  
该函数有3个功能:1.打开Binder设备文件;2.告诉Binder驱动自己是守护进程;3.进入无限循环,充当Server角色,等待Client的请求。

我们直接看第二个功能:

[cpp]  view plain  copy
 
  1. int binder_become_context_manager(struct binder_state *bs)  
  2. {  
  3.     return ioctl(bs->fd, BINDER_SET_CONTEXT_MGR, 0);  
  4. }  
这里通过ioctl来通知Binder驱动自己是守护进程

第三个功能进入循环,等待Client的请求:

[cpp]  view plain  copy
 
  1. void binder_loop(struct binder_state *bs, binder_handler func)  
  2. {  
  3.     int res;  
  4.     struct binder_write_read bwr;  
  5.     unsigned readbuf[32];  
  6.   
  7.     bwr.write_size = 0;  
  8.     bwr.write_consumed = 0;  
  9.     bwr.write_buffer = 0;  
  10.       
  11.     readbuf[0] = BC_ENTER_LOOPER;  
  12.     binder_write(bs, readbuf, sizeof(unsigned));  
  13.   
  14.     for (;;) {  
  15.         bwr.read_size = sizeof(readbuf);  
  16.         bwr.read_consumed = 0;  
  17.         bwr.read_buffer = (unsigned) readbuf;  
  18.   
  19.         res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);  
  20.   
  21.         if (res < 0) {  
  22.             LOGE("binder_loop: ioctl failed (%s)\n", strerror(errno));  
  23.             break;  
  24.         }  
  25.   
  26.         res = binder_parse(bs, 0, readbuf, bwr.read_consumed, func);  
  27.         if (res == 0) {  
  28.             LOGE("binder_loop: unexpected reply?!\n");  
  29.             break;  
  30.         }  
  31.         if (res < 0) {  
  32.             LOGE("binder_loop: io error %d %s\n", res, strerror(errno));  
  33.             break;  
  34.         }  
  35.     }  
  36. }  

最后总结一下,Service Manager成为Binder守护进程的过程是这样的:

1.打开/dev/binder文件:open("/dev/binder", O_RDWR);

2.建立128K内存映射:mmap(NULL, mapsize, PROT_READ, MAP_PRIVATE, bs->fd, 0);

3.通知Binder驱动它是守护进程:binder_become_context_manager(bs);

4.进入循环等待:binder_loop(bs, svcmgr_handler);

在整个过程中,Binder驱动建立了一个struct binder_proc结构,一个struct binder_thread结构,一个struct binder_node结构,这样Service_Manager就在Binder中担负起守护进程的职责了。

二.Server和Client是如何获得Service Manager接口的?(即defaultServiceManager接口是如何实现的)

Servvice Manager在Binder机制中既充当守护进程的角色也充当着Server的角色,但它与一般的Server不一样。对于一般的Server来说,Client想要获得Server的远程接口,必须通过Service Manager提供的getService来获得,这本身就是一个使用Binder机制来进行通信的过程。而对于Service Manager这个Server来说,Client想要获得Service Manager接口,却不必通过Binder机制来获得,因为Service Manager接口是个特殊的引用,它的引用句柄一定是0。

在Binder机制中,Server和Client拿到这个Service Manager接口之后怎么用呢?

对Server来说就是调用IServiceManager::addService这个接口来和Binder驱动交互;对于Client来说是调用IServiceManager::getService接口来和Binder驱动交互。

三.Server是如何把自己的服务启动起来的?Server Manager是如何为Server提供服务的?(即IServiceManager::addService接口是如何实现的)

这里通过一个例子老说明Binder机制中Server的启动过程。众所周知在安卓系统中提供了多媒体播放的功能 ,这个功能是以服务的形式提供的,下面通过分析MediaPlayerService的实现来了解Media Server的启动过程。

[cpp]  view plain  copy
 
  1. int main(int argc, char** argv)  
  2. {  
  3.     sp<ProcessState> proc(ProcessState::self());  
  4.     sp<IServiceManager> sm = defaultServiceManager();  
  5.     LOGI("ServiceManager: %p", sm.get());  
  6.     AudioFlinger::instantiate();  
  7.     MediaPlayerService::instantiate();  
  8.     CameraService::instantiate();  
  9.     AudioPolicyService::instantiate();  
  10.     ProcessState::self()->startThreadPool();  
  11.     IPCThreadState::self()->joinThreadPool();  
  12. }  
Server启动起来后,就会在一个循环中等待Client的请求。

四.Service Manager是如何为Client提供服务的?(即IServiceManager::getService接口是如何实现的)

假设Service Manager和MediaPlayerService已经启动完毕,Service Manager现在等待Client的请求。

这里举例说的Client便是MediaPlayer了,MediaPlayer继承于IMediaDeathNotifier类,里面有一个静态成员函数getMediaPlayerService,它通过IServiceManager::getService接口来获得MediaPlayerService的远程接口。

  1. // establish binder interface to MediaPlayerService  
  2. /*static*/const sp<IMediaPlayerService>&  
  3. IMediaDeathNotifier::getMediaPlayerService()  
  4. {  
  5.     LOGV("getMediaPlayerService");  
  6.     Mutex::Autolock _l(sServiceLock);  
  7.     if (sMediaPlayerService.get() == 0) {  
  8.         sp<IServiceManager> sm = defaultServiceManager();  
  9.         sp<IBinder> binder;  
  10.         do {  
  11.             binder = sm->getService(String16("media.player"));  
  12.             if (binder != 0) {  
  13.                 break;  
  14.              }  
  15.              LOGW("Media player service not published, waiting...");  
  16.              usleep(500000); // 0.5 s  
  17.         } while(true);  
  18.   
  19.         if (sDeathNotifier == NULL) {  
  20.         sDeathNotifier = new DeathNotifier();  
  21.     }  
  22.     binder->linkToDeath(sDeathNotifier);  
  23.     sMediaPlayerService = interface_cast<IMediaPlayerService>(binder);  
  24.     }  
  25.     LOGE_IF(sMediaPlayerService == 0, "no media player service!?");  
  26.     return sMediaPlayerService;  
  27. }  







































































































































































































































































































































































































































































































































































































































































































































































































































你可能感兴趣的:(Binder)