当前位置:操作系统 > 安卓/Android >>

Android开发之serviceManager分析

Android 开发之serviceManager分析
        在Android系统中用到最多的通信机制就是Binder,Binder主要由Client、Server、ServiceManager和Binder驱动程序组成。其中Client、Service和ServiceManager运行在用户空间,而Binder驱动程序运行在内核空间。核心组件就是Binder驱动程序了,而ServiceManager提供辅助管理的功能,无论是Client还是Service进行通信前首先要和ServiceManager取得联系。而ServiceManager是一个守护进程,负责管理Server并向Client提供查询Server的功能。

 

[html] 
在init.rc中servicemanager是作为服务启动的,而且是在zygote启动之前 
service servicemanager /system/bin/servicemanager 
    class core 
    user system 
    group system 
    critical 
    onrestart restart zygote 
    onrestart restart media 
    onrestart restart surfaceflinger 
    onrestart restart drm 

在init.rc中servicemanager是作为服务启动的,而且是在zygote启动之前
service servicemanager /system/bin/servicemanager
 class core
 user system
 group system
 critical
 onrestart restart zygote
 onrestart restart media
 onrestart restart surfaceflinger
 onrestart restart drm
源码位置:frameworks/base/cmds/servicemanager/service_manager.c

[html] 
int main(int argc, char** argv) 

    struct binder_state *bs; 
    void* svcmgr = BINDER_SERVICE_MANAGER; 
     
    bs = binder_open(128*1024); 
     
    binder_become_context_manager(bs); 
     
    svcmgr_handle = svcmgr; 
     
    binder_loop(bs, svcmgr_handler); 
     
    return 0; 

int main(int argc, char** argv)
{
 struct binder_state *bs;
 void* svcmgr = BINDER_SERVICE_MANAGER;
 
 bs = binder_open(128*1024);
 
 binder_become_context_manager(bs);
 
 svcmgr_handle = svcmgr;
 
 binder_loop(bs, svcmgr_handler);
 
 return 0;
}
 这里main函数主要有三个功能:
1)打开Binder设备文件
 首先我们来看看这个struct binder_state结构体
 struct binder_state
 {
         int fd;   // 文件描述符,打开/dev/binder设备
         void* mapped;  // 把设备文件/dev/binder映射到进程空间的起始地址
         unsigned mapsize; // 映射内存空间的大小
 };
 
 宏:#define BINDER_SERVICE_MANAGER ((void*)0)
 表示ServiceManager对应的句柄为0,表面自己是服务器管理者。其他的Server进程句柄值都是大于0的。

[html
struct binder_state* binder_open(unsigned mapsize) 

    struct binder_state* bs; 
    bs = malloc(sizeof(*bs)); 
    bs->fd = open("/dev/binder", O_RDWR); 
    bs->mapsize = mapsize; 
    bs->mapped = mmap(NULL, mapsize, PROT_READ, MAP_PRIVATE, bs->fd, 0); 
    return bs; 
}    
这里主要就是打开Binder设备,映射128K的内存地址空间 

struct binder_state* binder_open(unsigned mapsize)
{
 struct binder_state* bs;
 bs = malloc(sizeof(*bs));
 bs->fd = open("/dev/binder", O_RDWR);
 bs->mapsize = mapsize;
 bs->mapped = mmap(NULL, mapsize, PROT_READ, MAP_PRIVATE, bs->fd, 0);
 return bs;

这里主要就是打开Binder设备,映射128K的内存地址空间

2)告诉Binder驱动程序自己是Binder上下文管理者


[html]
<SPAN style="COLOR: #000000">int binder_become_context_manager(struct binder_state *bs) 

    return ioctl(bs->fd, BINDER_SET_CONTEXT_MGR, 0); 

调用驱动程序设置这个进程为管理者BINDER_SET_CONTEXT_MGR</SPAN> 

int binder_become_context_manager(struct binder_state *bs)
{
 return ioctl(bs->fd, BINDER_SET_CONTEXT_MGR, 0);
}
调用驱动程序设置这个进程为管理者BINDER_SET_CONTEXT_MGR3)进入一个无线循环,充当server角色,等待Client的请求

[html] 
void binder_loop(struct binder_state bs, binder_handler func) 

    struct binder_write_read bwr; 
    unsigned readbuf[32]; 
     
    bwr.write_size = 0; 
    bwr.write_consumed = 0; 
    bwr.write_buffer = 0; 
    readbuf[0] = BC_ENTER_LOOPER;   // 设置事件类型为LOOPER 
    // 调用ioctl函数,通知Binder设备servicemanager开始进入loop状态 
    binder_write(bs, readbuf, sizeof(unsigned)); 
     
    for(;;) { 
        bwr.read_size = sizeof(readbuf); 
        bwr.read_consumed = 0; 
        bwr.read_buffer = (unsigned)readbuf; 
        // 进入Binder设备缓冲区,检查是否有IPC请求 
        ioctl(bs->fd, BINDER_WRITE_READ, &bwr); 
        // 对于请求调用binder_parse进行解析处理 
        binder_parse(bs, 0, readbuf, bwr.read_consumed, func); 
    } 

 
这里我们看下struct binder_write_read这个结构体: 
struct binder_write_read{ 
    signed long write_size; 
    signed long write_consumed; // bytes consumed by driver 
    unsigned long write_buffer; 
    signed long read_size; 
    signed long read_consumed;  // bytes consumed by driver 
    unsigned long read_buffer; 
}; 
 
int binder_parse(struct binder_state *bs, struct binder_io *bio, uint32_t *ptr,  
            uint32_t size, binder_handler func) 

    uint32_t *end = ptr + (size / 4);    
    while(ptr < end) { 
        uint32_t cmd = *ptr++; 
        switch(cmd) { 
        ...... 
        case BR_TRANSACTOIN:{   // 收到请求进行处理 
            struct bindeer_txn *txn = (void*) ptr; 
            if(func) { 
                unsigned rdata[256/4]; 
     

补充:移动开发 , Android ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,