AndroidBinder机制解析

Android Binder机制解析

概述

Binder是Android系统中提供的一种IPC(进程间通信)机制。Android系统

是基于Linux内核而开发的,除了Binder之外,它还存在其他的IPC机制,如Pipe和Socket。所谓进程间通信,其实是一组编程接口,它能让程序员协调不同进程,使之在同一个操作系统中同时运行并进行信息的传递和交换。Binder机制在Android系统中具有重要的作用,Android的C/S架构,基本上都是基于Binder实现的,破解Binder机制,对破解Android源码,提升代码理解力具有重要意义。

 

                                                                         图1.1 IPC进程间通信示意图

 

 

         所谓C/S架构,顾名思义,从角色的角度上看会存在Client端和Server端,但在Android系统中,还存在一个统领全局的ServiceManager,它主要的作用是管理系统中各种服务,如CameraServer、MediaServer和ImageEffectService等。

                                                                  图1.2 Android系统C/S结构意图

  1. 图1.2中,任意两者间的通信都是进程间通信,并且是通过Binder实现的
  2. Server端作为一个服务,在启动时,需要将自己注册到ServiceManager中,故而它是ServicManager的一个客户端。
  3. Client端想要使用某个服务也必须先从ServiceManager中获取该服务的信息,故而Client也是ServiceManager的客户端。
  4. Client根据向ServiceManager获取到的信息,与Server建立通信通路,然后直接与Server进行交互,故而Client又是Server的客户端。
  5. 一个进程,既可以是客户端,也可以是服务端。

 

本节从概念和结构上简述了进程间通信和Android所采用的C/S架构角色之间的关系。Binder正是各种角色之间的沟通者、通信员。在Binder程序设计中,无论是客户端还是服务端,如果它想进行进程间通信,就必须建立Binder通信。但最重要的,还是各自业务本身的建设和完善。虽然Binder通信的建立至关重要,但它也仅仅是一个通信的建立而已,在看代码时,应保持清醒的头脑,将业务函数与通信建立函数区分开来,这样才能更迅速的找到自己感兴趣的代码,而不至于陷入人民战争(代码)的汪洋大海。下一章节将会以MediaServer为切入点,从代码角度对Binder机制进行解析。

 

MediaServer入口函数

CameraServer的入口函数如下所示,Linux可执行程序的入口函数就是一个main函数,不难看出,CameraServer就是在本进程中被创建。

int main(int argc __unused, char **argv __unused)

{

    signal(SIGPIPE, SIG_IGN);

 

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

    sp<IServiceManager> sm(defaultServiceManager());

    ALOGI("ServiceManager: %p", sm.get());

    InitializeIcuOrDie();

    MediaPlayerService::instantiate();

    ResourceManagerService::instantiate();

    registerExtensions();

    ProcessState::self()->startThreadPool();

    IPCThreadState::self()->joinThreadPool();

}

 

  1. ProcessState类的分析

ProcessState采用的是单例模式,所谓单例,就是指在当前进程中只有一个

ProcessState对象的实例。分析其构造函数,第一句话便调用了open_driver();用于打开/dev/binder这个设备,它是Linux中为完成进程间通信而专门设置的虚拟设备。在获取到binder设备文件描述符后,调用mmap为它分配一块内存来接收数据。

 

ProcessState::ProcessState()

    : mDriverFD(open_driver())

, mVMStart(MAP_FAILED)

......

    ,

{

if (mDriverFD >= 0) {

    //为打开的文件描述符map一块内存

        mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);

        if (mVMStart == MAP_FAILED) {

            close(mDriverFD);

            mDriverFD = -1;

        }

    }

}

分析open_driver()函数,通过

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值