简介

  Binder是Android系统提供的一种IPC(进程间通信)机制。由于Android是基于Linux内核的,因此,除了Binder外,还存在其他的IPC机制,例如管道和socket等。Binder相对于其他IPC机制来说,就更加灵活和方便了。Android系统基本上可以看作是一个基于Binder通信的C/S架构。Binder就像网络一样,把系统各个部分连接在了一起,因此它是非常重要的。

什么是Binder

Binder是android在内核中专门用于完成进程间通信而设置的一个虚拟设备(/dev/binder).

· ProcessState的构造函数悄悄地打开了Binder设备.每个进程只有一个ProcessState对象Process::self();
· 打开/dev/binder设备,这就相当于与内核的Binder驱动有了交互的通道。
· Binder的驱动代码在kernel/drivers/staing/android/binder.c中,另外该目录下还有一个binder.h头文件。
· /proc/binder目录下的内容可用来查看Binder设备的运行状况。
· 由于ProcessState的惟一性,因此一个进程只打开设备一次。

Client、Server和ServiceManager

在基于Binder通信的C/S架构体系中,除了C/S架构所包括的Client端和Server端外,Android还有一个全局的ServiceManager端,它的作用是管理系统中的各种服务(Service)。Client、Server和ServiceManager这三者之间的交互关系,如图所示

注意:一个Server进程可以注册多个Service,就像即将讲解的MediaServer一样。
根据上图,可以得出如下结论:
· Server进程要先注册一些Service到ServiceManager中,所以Server是ServiceManager的客户端,而ServiceManager就是服务端了。
· 如果某个Client进程要使用某个Service,必须先到ServiceManager中获取该Service的相关信息,所以Client是ServiceManager的客户端。
· Client根据得到的Service信息建立与Service所在的Server进程通信的通路,然后就可以直接与Service交互了,所以Client也是Server的客户端。
· 最重要的一点是,三者的交互都是基于Binder通信的,所以通过任意两者之间的关系,都可以揭示Binder的奥秘。

  这里,要重点强调的是Binder通信与C/S架构之间的关系。Binder只是为C/S架构提供了一种通信的方式,我们完全可以采用其他IPC方式进行通信,例如,系统中有很多其他的程序采用的就是Socket或Pipe的方法进行进程间通信。很多初学者可能觉得Binder较复杂,尤其是看到诸如BpXXX、BnXXX之类的定义便感到头晕,这很有可能是把Binder通信层结构和应用的业务层结构搞混了。如果能搞清楚这二者的关系,完全可以自己实现一个不使用BpXXX和BnXXX的Service。须知,ServiceManager可并没有使用它们。

BpBinder和BBinder

BpBinder和BBinder都是Android中与Binder通信相关的代表,它们都从IBinder类中派生而来,如图


· BpBinder是客户端用来与Server交互的代理类,p即Proxy的意思。
· BBinder则是proxy相对的一端,它是proxy交互的目的端。如果说Proxy代表客户端,那么BBinder则代表服务端。这里的BpBinder和BBinder是一一对应的,即某个BpBinder只能和对应的BBinder交互。我们当然不希望通过BpBinderA发送的请求,却由BBinderB来处理。
· Binder系统通过handler来对应BBinder,在整个Binder系统中handler为0代表的就是ServiceManager所对应的BBinder.

MS(MediaServe)与SM(ServiceManager)用binder通信示例

在MediaServer进程向ServiceManager进程注册MediaPlayerService为例

在MediaServer进程中:
1,构造一个ProcessState,用ProcessState::self(),每个进程中只有一个ProcessState
2,ProcessState::self()中打开binder设备.
3,defaultServiceManager函数得到一个IServiceManager,实际得到BpServiceManager,它是IServiceManager的后代.用来和ServiceManager进程用binder通信,IServiceManager实际是用interface_cast函数模板,利用BpBinder对象作为参数新建了一个BpServiceManager对象.
4,用getStrongProxyForHandle(handler的值,0代表ServiceManager的BBinder),BpBinder和BBinder是一一对应的.Binder系统通过handler来对应BBinder
5,Android巧妙地通过DECLARE_META_INTERFACE和IMPLENT宏,将业务和通信牢牢地钩在了一起.DECLARE_META_INTERFACE在IServiceManager内部声明了业务函数.

6,addService函数中把请求数据打包成data后,传给了BpBinder的transact函数,把通信的工作交给了BpBinder.

7,在BpBinder的transact函数中使用了IPCThreadState

每个线程都有一个IPCThreadState,每个IPCThreadState中都有一个mIn、一个mOut,其中mIn是用来接收
来自Binder设备的数据的,而mOut则是用来存储发往Binder设备的数据的。

在ServiceManager进程中:
1,binder_open,打开binder设备
2,binder_become_context_manager,成为manager
3,binder_loop,处理客户端发过来的请求。
4,接收到请求,交给binder_parse,最终会调用func来处理这些请求
5,通常往binder_loop中传的那个函数指针是svcmgr_handler.这函数可集中处理.

6,do_add_service这个函数,它最终完成了对addService请求的处理实现

ServiceManager存在的意义

为何需要一个ServiceManager,其重要作用何在?
· ServiceManger能集中管理系统内的所有服务,它能施加权限控制,并不是任何进程都能注册服务。
· ServiceManager支持通过字符串名称来查找对应的Service。这个功能很像DNS。第6章 深入理解Binder
· 由于各种原因,Server进程可能生死无常。如果让每个Client都去检测,压力实在太大。现在有了统一的管理机构,Client只需要查询ServiceManager,就能把握动向,得到最新信息。这可能正ServiceManager存在的最大意义吧。

IServiceManager的家族

· IServiceManager、BpServiceManager和BnServiceManager都与业务逻辑相关。
· BnServiceManager同时从BBinder派生,表示它可以直接参与Binder通信。
· BpServiceManager虽然从BpInterface中派生,但是这条分支似乎与BpBinder没有关系。
· BnServiceManager是一个虚类,它的业务函数最终需要子类来实现。

重要说明:以上这些关系很复杂,但ServiceManager并没有使用错综复杂的派生关系,它直接打开Binder设备并与之交互。

Binder通信层和业务层的关系

Android 内核初识(8)Binder的更多相关文章

  1. 【转】Android 内核初识(6)SystemServer进程

    简介 SystemServer的进程名实际上叫做“system_server”,通常简称为SS. 系统中的服务驻留在其中,常见的比如WindowManagerServer(Wms).ActivityM ...

  2. Android 内核初识(6)SystemServer进程

    简介 SystemServer的进程名实际上叫做“system_server”,通常简称为SS. 系统中的服务驻留在其中,常见的比如WindowManagerServer(Wms).ActivityM ...

  3. Android 内核初识(5)Zygote进程

    简介 Zygote本身是一个Native的应用程序,和驱动.内核等均无关系.Zygote是由init进程根据init.rc文件中的配置项而创建的. zygote最初的名字叫“app_process”, ...

  4. Android 内核初识(3)init进程

    init是一个进程,确切地说,它是Linux系统中用户空间的第一个进程.由于Android是基于Linux内核的,所以init也是Android系统中用户空间的第一个进程,它的进程号是1.作为天字第一 ...

  5. Android 内核初识(1)下载源码需求与教程

    官方文档: http://source.android.com/source/requirements.html  Requirements The Android build is routinel ...

  6. Android 内核初识(7)RefBase、LightRefBase、sp和wp

    简介 RefBase是Android中所有对象的始祖,类似MFC中的CObject及Java中的Object对象.在Android中,RefBase结合sp和wp,实现了一套通过引用计数的方法来控制对 ...

  7. Android 内核初识(4)属性服务器

    简介 Windows平台上有一个叫注册表的东西.注册表可以存储一些类似key/value的键值对.一般而言,系统或某些应用程序会把自己的一些属性存储在注册表中,即使下次系统重启或应用程序重启,它还能够 ...

  8. Android 内核初识(2)android系统架构

    以模块角度 以Java,native,kernel角度

  9. 写给 Android 应用工程师的 Binder 原理剖析

    写给 Android 应用工程师的 Binder 原理剖析 一. 前言 这篇文章我酝酿了很久,参考了很多资料,读了很多源码,却依旧不敢下笔.生怕自己理解上还有偏差,对大家造成误解,贻笑大方.又怕自己理 ...

随机推荐

  1. Asp.net 定时写入文本记录

    Asp.net 定时写入文本记录 public static string FileAddress = "c:\\TimerLog.txt"; protected void Pag ...

  2. Windows Forms(二)

    导读 1.用VS创建一个Windows Forms程序 2.分析上面的程序 3.Mediator pattern(中介者模式) 4.卡UI怎么办——BackgroundWorker组件 用VS创建一个 ...

  3. java多线程 join方法以及优先级方法

    /*join:当A线程执行到了B线程的.join()方法时,A就会等待.等B线程都执行完,A才会执行. join可以用来临时加入线程执行. 1.线程使用join方法,主线程就停下,等它执行完,那么如果 ...

  4. 基于SMB共享文件夹的上传于下载

    需要用到的jar包   http://pan.baidu.com/s/1skQFk77 1.首先在一台电脑上设置共享文件夹 ----上传下载的方法类 package com.strongit.tool ...

  5. How to: Declare encoding UTF-8 in python

    References: http://stackoverflow.com/questions/12238307/declaring-encoding-in-python http://stackove ...

  6. cannot convert from '_TCHAR *' to 'char *'

    Reference: Why can't convert TCHAR* to char* Need to Use Multi-Byte Character Set in project's setti ...

  7. DataList和Repeater

    DataList和Repeater是两个十分有用的控件,在新闻列表和图片展示的地方经常用到.在这里简单的把他们介绍一下. 1.DataList: 前端页面: <asp:DataList ID=& ...

  8. Linux CPU亲缘性详解

    前言 在淘宝开源自己基于nginx打造的tegine服务器的时候,有这么一项特性引起了笔者的兴趣.“自动根据CPU数目设置进程个数和绑定CPU亲缘性”.当时笔者对CPU亲缘性没有任何概念,当时作者只是 ...

  9. C# 读取快捷方式指向的文件

    C# 读取快捷方式指向的文件 [Flags()] public enum SLR_FLAGS { SLR_NO_UI = 0x1, SLR_ANY_MATCH = 0x2, SLR_UPDATE = ...

  10. nginx中的try_files指令解释

    try_files 指令的官方介绍比较让人摸不着头脑,经网上一番总结查看,try_files最核心的功能是可以替代rewrite.   try_files   语法: try_files file . ...