Android Binder设计与实现 – 设计篇
- 格式:doc
- 大小:939.00 KB
- 文档页数:19
安卓binder原理安卓Binder原理一、引言在安卓系统中,进程间通信(IPC)是非常重要的,而Binder作为安卓系统中的进程间通信机制,扮演着关键的角色。
本文将介绍安卓Binder的原理及其相关概念,以便更好地理解安卓系统的工作原理。
二、安卓Binder的概述Binder是安卓系统中一种轻量级的IPC机制,其设计目标是为了提供高效的进程间通信能力。
Binder主要由Binder驱动、Binder服务和Binder代理组成。
1. Binder驱动Binder驱动是位于内核空间的模块,负责处理进程间通信的底层操作。
它提供了一组接口供用户空间进程使用,用于创建Binder节点、发送和接收Binder消息等操作。
2. Binder服务Binder服务是安卓系统中的后台服务,它可以通过Binder驱动与其他进程进行通信。
每个Binder服务都有一个唯一的标识符,称为Binder引用。
通过Binder引用,其他进程可以找到并与该服务通信。
3. Binder代理Binder代理是位于用户空间的模块,负责将进程间通信的请求转发给相应的Binder服务。
它通过Binder驱动与Binder服务进行交互,并将结果返回给请求方。
三、Binder的工作原理Binder的工作原理可以分为三个步骤:注册服务、获取引用和发起调用。
1. 注册服务Binder服务首先需要在系统中注册自己,以便其他进程可以找到并与之通信。
注册服务时,Binder服务会创建一个Binder节点,并向Binder驱动注册该节点。
注册成功后,Binder服务会获得一个唯一的Binder引用。
2. 获取引用其他进程想要与已注册的Binder服务通信,就需要获取该服务的Binder引用。
获取引用的过程是通过Binder代理完成的。
Binder 代理首先通过Binder驱动找到对应的Binder节点,然后获取该节点的引用,并将引用返回给请求方。
3. 发起调用一旦获取到Binder引用,请求方可以通过Binder代理向对应的Binder服务发起调用。
Android图⽂详解Binder进程通信底层原理⽬录什么是进程间通信什么是 BinderAndroid 中 IPC 的⽅式Binder 优势Linux 传统的 IPC 原理基本概念进程隔离进程空间划分系统调⽤传统 IPC 通信原理Binder IPC原理Binder 采⽤分层架构设计Binder 驱动Binder IPC 内存映射Android Binder 原理图Bind 原理图Bind 原理图交互Bind 原理图交互路线之前了解到进程与多进程,涉及多进程不可避免的遇到了进程间通信,说到进程间通信,Binder 成了⼀道绕不过的坎。
接下来咱们逐⼀了解。
什么是进程间通信进程间通信(IPC,Inner Process Comunication),就是指不同进程之间的信息传递。
进程是系统进⾏资源分配和调度的基本单位,是操作系统的结构的基础;⼀个应⽤⾄少有⼀个进程,⼀个进程中有包含了多个线程(线程是CPU调度的最⼩单位),进程相当于是线程的ViewGroup,线程相当于操作系统分配个进程的View。
什么是 BinderBinder 是 Android 系统中进程间通信机制(IPC)的⼀种⽅式,它是这些进程间通讯的桥梁。
正如其名"粘合剂"⼀样,它把系统中各个组件粘合到了⼀起,是各个组件的桥梁。
应⽤层:是⼀个能发起通信的Java类。
Client:是对 Binder 代理对象,是 Binder 实体对象的⼀个远程代理。
Server:是 Server 中的 Binder 实体对象。
机制:是⼀种进程间通信机制。
驱动:是⼀个虚拟物理设备驱动;如startActivity的简图:这⾥就⽤到了 Binder 通信,你会发现这⾥还有 Socker 通信,那我为什么要⽤ Binder ⽽不⽤ Socket。
Android 中 IPC 的⽅式名称特点使⽤场景Bundle只能传输实现了序列化或者⼀些Android⽀持的特殊对象适合⽤于四⼤组件之间的进程交互⽂件不能做到进程间的即时通信,并且不适合⽤于⾼并发的场景适合⽤于SharedPreference以及IO操作ContentProvider可以访问较多的数据,⽀持⼀对多的⾼并发访问,因为ContentProvider已经⾃动做好了关于并发的机制适合⽤于⼀对多的数据共享并且需要对数据进⾏频繁的CRUD操作Socket通过⽹络传输字节流,⽀持⼀对多的实时通信,但是实现起来⽐较复杂适合⽤于⽹络数据共享Messenger底层原理是AIDL,只是对其做了封装,但是不能很好的处理⾼并发的场景,并且传输的数据只能⽀持Bundle类型多进程、单线程且线程安全AIDL功能强⼤,使⽤Binder机制,⽀持⼀对多的⾼并发实时通信,但是需要处理好线程同步⼀对多并且有远程进程通信的场景Binder 优势出发点Binder共享内存Socket性能拷贝⼀次⽆需拷贝拷贝两次特点基于C/S架构,易⽤性⾼控制复杂,易⽤性差基于C/S架构,通⽤接⼝,传输效率低、开销⼤安全每个APP分配UID,同时⽀持实名和匿名依赖上层协议,访问接⼊点是开放的不安全依赖上层协议,访问接⼊点是开放的不安全通过以上对⽐,Android 最终选择了⾃建⼀套兼顾好⽤、⾼效、安全的 Binder。
Android进程间通信-Binder机制目录一.简要介绍和学习计划二.Service Manager成为Binder守护进程之路三.Server和Client获得Service Manager接口之路四.Server启动过程源代码分析五.Client获得Server远程接口过程源代码分析六.应用程序框架层的Java接口源代码分析一、Android进程间通信(IPC)机制Binder 简要介绍和学习计划我们知道,在Android系统中,每一个应用程序都是由一些Activity和Service组成的,一般Service 运行在独立的进程中,而 不同的Activity有可能运行在同一个进程中,也可能运行在不同的进程中。
这很自然地想到,不在同一个进程的Activity和Service是如何 通信的呢?毕竟它们要协作在一起来完成一个完整的应用程序功能。
这就是本文中要介绍的Android系统进程间通信机制Binder了。
我们知道,Android系统是基于Linux内核的,而Linux内核继承和兼容了丰富的Unix系统进程间通信(IPC)机制。
有传统的管道 (Pipe)、信号(Signal)和跟踪(Trace),这三项通信手段只能用于父进程与子进程之间,或者兄弟进程之间;后来又增加了命令管道 (Named Pipe),使得进程间通信不再局限于父子进程或者兄弟进程之间;为了更好地支持商业应用中的事务处理,在AT&T的Unix 系统V中,又增加了 三种称为“System V IPC”的进程间通信机制,分别是报文队列(Message)、共享内存(Share Memory)和信号量(Semaphore);后来BSD Unix对“System V IPC”机制进行了重要的扩充,提供了一种称为插口(Socket)的进程间通信机制。
若想进一步详细了解这些进程间通信机制,建议参考Android学习启动篇一文中提到《Linux内核源代码情景分析》一书。
Android Binder设计与实现–设计篇摘要Binder是Android系统进程间通信(IPC)方式之一。
Linux已经拥有管道、system V IPC、socket等IPC手段,却还要倚赖Binder来实现进程间通信,说明Binder具有无可比拟的优势。
深入了解Binder并将之与传统 IPC做对比有助于我们深入领会进程间通信的实现和性能优化。
本文将对Binder的设计细节做一个全面的阐述,首先通过介绍Binder通信模型和Binder通信协议了解Binder的设计需求;然后分别阐述Binder在系统不同部分的表述方式和起的作用;最后还会解释Binder在数据接收端的设计考虑,包括线程池管理,内存映射和等待队列管理等。
通过本文对Binder的详细介绍以及与其它IPC通信方式的对比,读者将对Binder的优势和使用Binder 作为Android主要IPC方式的原因有深入了解。
1.引言基于Client-Server的通信方式广泛应用于从互联网和数据库访问到嵌入式手持设备内部通信等各个领域。
智能手机平台特别是Android 系统中,为了向应用开发者提供丰富多样的功能,这种通信方式更是无处不在,诸如媒体播放,视音频捕获,到各种让手机更智能的传感器(加速度、方位、温度、光亮度等)都由不同的Server负责管理,应用程序只需作为Client与这些Server建立连接便可以使用这些服务,花很少的时间和精力就能开发出令人眩目的功能。
Client-Server方式的广泛采用对进程间通信(IPC)机制是一个挑战。
目前linux 支持的IPC包括传统的管道、System V IPC、即消息队列/共享内存/信号量,以及socket中只有socket支持Client-Server的通信方式。
当然也可以在这些底层机制上架设一套协议来实现Client-Server通信,但这样增加了系统的复杂性,在手机这种条件复杂,资源稀缺的环境下可靠性也难以保证。
androidbinder机制原理Android Binder 机制原理什么是 Android Binder 机制?Android Binder 机制是 Android 系统中用于进行进程间通信(IPC)的核心机制之一。
它负责在不同的 Android 组件之间传递数据和进行远程方法调用。
为什么 Android 需要 Binder 机制?Android 系统的设计中,每个应用程序运行在独立的进程中,它们之间需要进行信息交换和协作。
而 Binder 机制提供了一种高效、安全和可靠的方式来实现进程间通信。
Binder 机制的关键组件Binder 机制主要由以下几个关键组件组成:1. 服务端(Server)服务端是提供服务的组件,它通过继承Binder类并实现对应的接口,将服务提供给客户端使用。
2. 客户端(Client)客户端是使用服务的组件,它通过 Binder 机制与服务端进行通信,获取所需的数据或调用对应的方法。
3. Binder 驱动(Binder Driver)Binder 驱动是位于 Linux 内核中的模块,负责处理进程间通信的底层操作,如进程注册、线程管理、进程间通信等。
4. Binder 通信线程(Binder Communication Thread)Binder 通信线程是运行在客户端和服务端进程中的线程,负责处理进程间通信的具体细节,如数据传输、对象序列化等。
5. Binder 编译器(Binder Compiler)Binder 编译器是将服务端定义的接口文件生成对应的 Java 接口和代理类,用于客户端与服务端的通信。
Binder 机制的工作流程Android Binder 机制的工作流程可以简要描述如下:1.客户端通过绑定机制连接到服务端,获取服务的引用。
2.客户端通过服务的引用调用远程方法,并传递相应的参数。
3.客户端的请求通过 Binder 通信线程封装成消息并发送给服务端。
binder 机制深入解析Binder 机制是 Android 系统中的一种进程间通信(IPC)机制,它允许不同进程之间进行数据交换和通信。
Binder 机制的核心是Binder 驱动程序,它提供了一种高效的进程间通信方式,使得Android 系统中的各个组件能够相互通信并协同工作。
首先,让我们从 Binder 的基本工作原理开始。
Binder 机制的核心是 Binder 驱动程序,它负责进程间通信的建立和管理。
在Binder 机制中,有三种角色,客户端、服务端和 Binder 驱动程序。
客户端通过 Binder 对象与服务端进行通信,Binder 驱动程序负责传输数据和消息。
其次,我们可以深入了解 Binder 机制的底层实现。
Binder 机制的底层实现涉及到内核空间和用户空间的交互,涉及到线程调度、内存管理等底层操作。
Binder 驱动程序通过内核提供的特殊接口与用户空间进行通信,实现进程间的数据传输和通信。
另外,我们可以探讨 Binder 机制在 Android 系统中的应用。
Binder 机制在 Android 系统中被广泛应用于各种组件之间的通信,比如 Activity 与 Service 之间的通信、不同应用程序之间的通信等。
Binder 机制的高效性和稳定性使得 Android 系统能够实现复杂的功能和交互。
此外,我们还可以讨论 Binder 机制的优势和局限性。
Binder机制的优势在于高效的进程间通信、低延迟、支持大数据传输等;而局限性在于复杂度较高、需要谨慎处理内存管理等方面。
总的来说,Binder 机制作为 Android 系统中的重要组成部分,对于进程间通信起着至关重要的作用。
通过深入解析 Binder 机制的基本原理、底层实现、应用和优劣势,我们可以更好地理解Android 系统中的进程间通信机制,为开发高效稳定的 Android 应用程序提供参考和指导。
Android深⼊浅出之Binder机制Android深⼊浅出之Binder机制⼀说明Android系统最常见也是初学者最难搞明⽩的就是Binder了,很多很多的Service就是通过Binder机制来和客户端通讯交互的。
所以搞明⽩Binder的话,在很⼤程度上就能理解程序运⾏的流程。
我们这⾥将以MediaService的例⼦来分析Binder的使⽤:l ServiceManager,这是Android OS的整个服务的管理程序l MediaService,这个程序⾥边注册了提供媒体播放的服务程序MediaPlayerService,我们最后只分析这个l MediaPlayerClient,这个是与MediaPlayerService交互的客户端程序下⾯先讲讲MediaService应⽤程序。
⼆ MediaService的诞⽣MediaService是⼀个应⽤程序,虽然Android搞了七七⼋⼋的JAVA之类的东西,但是在本质上,它还是⼀个完整的Linux操作系统,也还没有⽜到什么应⽤程序都是JAVA写。
所以,MS(MediaService)就是⼀个和普通的C++应⽤程序⼀样的东西。
MediaService的源码⽂件在:framework\base\Media\MediaServer\Main_mediaserver.cpp中。
让我们看看到底是个什么玩意⼉!int main(int argc, char** argv){//FT,就这么简单??//获得⼀个ProcessState实例sp<ProcessState> proc(ProcessState::self());//得到⼀个ServiceManager对象sp<IServiceManager> sm = defaultServiceManager();MediaPlayerService::instantiate();//初始化MediaPlayerService服务ProcessState::self()->startThreadPool();//看名字,启动Process的线程池?IPCThreadState::self()->joinThreadPool();//将⾃⼰加⼊到刚才的线程池?}其中,我们只分析MediaPlayerService。
Android Binder设计与实现–设计篇摘要Binder是Android系统进程间通信(IPC)方式之一。
Linux已经拥有管道,system V IPC,socket等IPC手段,却还要倚赖Binder来实现进程间通信,说明Binder具有无可比拟的优势。
深入了解Binder并将之与传统 IPC做对比有助于我们深入领会进程间通信的实现和性能优化。
本文将对Binder的设计细节做一个全面的阐述,首先通过介绍Binder通信模型和 Binder通信协议了解Binder的设计需求;然后分别阐述Binder在系统不同部分的表述方式和起的作用;最后还会解释Binder在数据接收端的设计考虑,包括线程池管理,内存映射和等待队列管理等。
通过本文对Binder的详细介绍以及与其它IPC通信方式的对比,读者将对Binder的优势和使用Binder作为Android主要IPC方式的原因有深入了解。
1 引言基于Client-Server的通信方式广泛应用于从互联网和数据库访问到嵌入式手持设备内部通信等各个领域。
智能手机平台特别是Android系统中,为了向应用开发者提供丰富多样的功能,这种通信方式更是无处不在,诸如媒体播放,视频音频捕获,到各种让手机更智能的传感器(加速度,方位,温度,光亮度等)都由不同的Server负责管理,应用程序只需做为Client与这些Server建立连接便可以使用这些服务,花很少的时间和精力就能开发出令人眩目的功能。
Client-Server方式的广泛采用对进程间通信(IPC)机制是一个挑战。
目前linux支持的IPC包括传统的管道,System V IPC,即消息队列/共享内存/信号量,以及socket中只有socket支持Client-Server的通信方式。
当然也可以在这些底层机制上架设一套协议来实现Client-Server通信,但这样增加了系统的复杂性,在手机这种条件复杂,资源稀缺的环境下可靠性也难以保证。
另一方面是传输性能。
socket作为一款通用接口,其传输效率低,开销大,主要用在跨网络的进程间通信和本机上进程间的低速通信。
消息队列和管道采用存储-转发方式,即数据先从发送方缓存区拷贝到内核开辟的缓存区中,然后再从内核缓存区拷贝到接收方缓存区,至少有两次拷贝过程。
共享内存虽然无需拷贝,但控制复杂,难以使用。
表 1 各种IPC方式数据拷贝次数IPC 数据拷贝次数共享内存0Binder 1Socket/管道/消息队列 2还有一点是出于安全性考虑。
Android作为一个开放式,拥有众多开发者的的平台,应用程序的来源广泛,确保智能终端的安全是非常重要的。
终端用户不希望从网上下载的程序在不知情的情况下偷窥隐私数据,连接无线网络,长期操作底层设备导致电池很快耗尽等等。
传统IPC没有任何安全措施,完全依赖上层协议来确保。
首先传统IPC的接收方无法获得对方进程可靠的UID/PID(用户ID/进程ID),从而无法鉴别对方身份。
Android为每个安装好的应用程序分配了自己的UID,故进程的UID是鉴别进程身份的重要标志。
使用传统IPC 只能由用户在数据包里填入UID/PID,但这样不可靠,容易被恶意程序利用。
可靠的身份标记只有由IPC机制本身在内核中添加。
其次传统IPC访问接入点是开放的,无法建立私有通道。
比如命名管道的名称,system V的键值,socket的ip地址或文件名都是开放的,只要知道这些接入点的程序都可以和对端建立连接,不管怎样都无法阻止恶意程序通过猜测接收方地址获得连接。
基于以上原因,Android需要建立一套新的IPC机制来满足系统对通信方式,传输性能和安全性的要求,这就是Binder。
Binder基于Client-Server通信模式,传输过程只需一次拷贝,为发送发添加UID/PID身份,既支持实名Binder也支持匿名Binder,安全性高。
2 面向对象的 Binder IPCBinder使用Client-Server通信方式:一个进程作为Server提供诸如视频/音频解码,视频捕获,地址本查询,网络连接等服务;多个进程作为Client向Server发起服务请求,获得所需要的服务。
要想实现Client-Server通信据必须实现以下两点:一是server 必须有确定的访问接入点或者说地址来接受Client的请求,并且Client可以通过某种途径获知Server的地址;二是制定Command- Reply协议来传输数据。
例如在网络通信中Server的访问接入点就是Server主机的IP地址+端口号,传输协议为TCP协议。
对Binder而言,Binder可以看成Server提供的实现某个特定服务的访问接入点, Client通过这个‘地址’向Server发送请求来使用该服务;对Client而言,Binder可以看成是通向Server的管道入口,要想和某个 Server通信首先必须建立这个管道并获得管道入口。
与其它IPC不同,Binder使用了面向对象的思想来描述作为访问接入点的Binder及其在Client中的入口:Binder是一个实体位于 Server中的对象,该对象提供了一套方法用以实现对服务的请求,就象类的成员函数。
遍布于client中的入口可以看成指向这个binder 对象的'指针',一旦获得了这个‘指针’就可以调用该对象的方法访问server。
在Client 看来,通过Binder'指针'调用其提供的方法和通过指针调用其它任何本地对象的方法并无区别,尽管前者的实体位于远端Server中,而后者实体位于本地内存中。
'指针'是C++的术语,而更通常的说法是引用,即Client通过Binder的引用访问Server。
而软件领域另一个术语‘句柄’也可以用来表述Binder在Client中的存在方式。
从通信的角度看,Client中的Binder也可以看作是Server Binder的‘代理’,在本地代表远端Server为Client提供服务。
本文中会使用‘引用’或‘句柄’这个两广泛使用的术语。
面向对象思想的引入将进程间通信转化为通过对某个Binder对象的引用调用该对象的方法,而其独特之处在于Binder对象是一个可以跨进程引用的对象,它的实体位于一个进程中,而它的引用却遍布于系统的各个进程之中。
最诱人的是,这个引用和java里引用一样既可以是强类型,也可以是弱类型,而且可以从一个进程传给其它进程,让大家都能访问同一Server,就象将一个对象或引用赋值给另一个引用一样。
Binder模糊了进程边界,淡化了进程间通信过程,整个系统仿佛运行于同一个面向对象的程序之中。
形形色色的Binder对象以及星罗棋布的引用仿佛粘接各个应用程序的胶水,这也是Binder在英文里的原意。
当然面向对象只是针对应用程序而言,对于Binder驱动和内核其它模块一样使用C语言实现,没有类和对象的概念。
Binder驱动为面向对象的进程间通信提供底层支持。
3 Binder 通信模型Binder框架定义了四个角色:Server,Client,ServiceManager(以后简称SMgr)以及驱动。
其中 Server,Client,SMgr运行于用户空间,驱动运行于内核空间。
这四个角色的关系和互联网类似:Server是服务器,Client是客户终端,SMgr是域名服务器(DNS),驱动是路由器。
3.1 Binder 驱动和路由器一样,Binder驱动虽然默默无闻,却是通信的核心。
尽管名叫‘驱动’,实际上和硬件设备没有任何关系,只是实现方式和设备驱动程序是一样的:它工作于内核态,提供open(),mmap(),poll(),ioctl()等标准文件操作,以字符驱动设备中的misc设备注册在设备目录 /dev下,用户通过/dev/binder访问该它。
驱动负责进程之间Binder通信的建立,Binder在进程之间的传递,Binder引用计数管理,数据包在进程之间的传递和交互等一系列底层支持。
驱动和应用程序之间定义了一套接口协议,主要功能由ioctl()接口实现,不提供 read(),write()接口,因为ioctl()灵活方便,且能够一次调用实现先写后读以满足同步交互,而不必分别调用write()和 read()。
3.2 ServiceManager 与实名Binder和DNS类似,SMgr的作用是将字符形式的Binder名字转化成Client中对该Binder的引用,使得Client能够通过Binder名字获得对Server中Binder实体的引用。
注册了名字的Binder叫实名Binder,就象每个网站除了有IP地址外都有自己的网址。
Server创建了Binder实体,为其取一个字符形式,可读易记的名字,将这个Binder连同名字以数据包的形式通过Binder驱动发送给 SMgr,通知SMgr注册一个名叫张三的Binder,它位于某个Server中。
驱动为这个穿过进程边界的Binder创建位于内核中的实体节点以及 SMgr对实体的引用,将名字及新建的引用传递给SMgr。
SMgr收数据包后,从中取出名字和引用填入一张查找表中。
细心的读者可能会发现其中的蹊跷:SMgr是一个进程,Server是另一个进程,Server向SMgr注册Binder必然会涉及进程间通信。
当前实现的是进程间通信却又要用到进程间通信,这就好象蛋可以孵出鸡前提却是要找只鸡来孵蛋。
Binder的实现比较巧妙:预先创造一只鸡来孵蛋。
SMgr和其它进程同样采用Binder通信,SMgr是Server端,有自己的Binder实体,其它进程都是Client,需要通过这个 Binder的引用来实现Binder的注册,查询和获取。
SMgr提供的Binder比较特殊,它没有名字也不需要注册,当一个进程使用BINDER_SET_CONTEXT_MGR命令将自己注册成SMgr时Binder驱动会自动为它创建Binder实体(这就是那只预先造好的鸡)。
其次这个Binder的引用在所有Client中都固定为0而无须通过其它手段获得。
也就是说,一个Server若要向SMgr注册自己Binder就必需通过0这个引用和SMgr的Binder通信。
类比网络通信,0号引用就好比域名服务器的地址,你必须手工或动态配置好。
要注意这里说的Client是相对SMgr而言的,一个应用程序是个提供服务的Server,但对SMgr来说它仍然是个Client。
3.3 Client 获得实名Binder的引用Server向SMgr注册了Binder实体及其名字后,Client就可以通过名字获得该Binder的引用了。