Android深入浅出之Binder机制
- 格式:doc
- 大小:213.00 KB
- 文档页数:26
安卓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 是一种用于进程间通信(IPC)的机制。
Binder 机制允许一个进程的代码调用另一个进程中的代码,通常在Android 中用于实现不同应用程序组件(例如服务)之间的通信。
在Binder 机制中,有两个主要的角色:Binder 服务和Binder 客户端。
Binder 服务通常运行在一个独立的进程中,而Binder 客户端则希望与服务进行通信。
为了进行通信,服务需要提供一个Binder 接口,而客户端需要获取到该接口以调用服务提供的方法。
这就涉及到Binder Stub。
Binder Stub:Binder Stub 是一个在客户端进程中的代理对象,用于代表服务端的实际对象。
在Android 中,Stub 通常是由系统自动生成的,并负责处理客户端发起的远程调用请求。
当客户端调用Binder 接口中的方法时,实际的工作是由Stub 完成的。
具体而言,Binder Stub 的工作包括:1. 接收远程调用请求:当客户端调用Binder 接口的方法时,实际上是通过Binder Stub 发送远程调用请求到服务端的对应Binder 对象。
2. 序列化和反序列化参数:Binder Stub 负责将客户端传递的参数序列化为二进制数据,并将服务端返回的结果反序列化为适当的数据类型。
3. 将请求发送到服务端:Binder Stub 将序列化后的请求发送到服务端,并等待服务端的响应。
4. 接收并处理服务端的响应:一旦服务端处理完请求,它将结果序列化并通过Binder Stub 发送回客户端。
5. 通知客户端调用完成:Binder Stub 负责通知客户端,使其能够继续执行。
在整个过程中,Binder Stub 充当了客户端和服务端之间的桥梁,隐藏了底层IPC 细节,使得远程调用就像本地调用一样。
这样,客户端不需要了解服务端的实际实现,而只需要通过Binder 接口与Stub 进行交互。
Android进程间的通信(IPC)机制的原理基于Linux内核提供的进程间通信机制(IPC)实现。
在Android系统中,Binder是其中的一种跨进程通信机制。
Binder机制中,每个进程都有一个Binder驱动程序,负责管理该进程中的所有Binder对象。
每个Binder对象都有一个唯一的标识符,称为Binder标识符(Binder identity),可以用于在进程之间传递Binder 引用。
在Binder机制中,客户端和服务端进程之间可以建立一个通信通道(communication channel)。
客户端可以通过这个通道向服务端发送请求,服务端可以处理请求并返回结果。
Binder机制中的主要组件包括以下几个部分:1. Binder驱动程序:负责管理Binder对象,以及为客户端进程和服务进程之间建立通信通道。
2. Binder对象:具有唯一标识符的对象,用于在进程之间传递引用。
3. Binder接口:定义了客户端可以调用的方法,以及服务端可以实现的方法。
4. Binder代理(Proxy):客户端进程中的对象,用于与服务端进程通信,并代表客户端调用服务端的方法。
5. Binder Stub:服务端进程中的对象,用于实现Binder接口,并处理客户端发送的请求。
使用Binder机制可以实现跨进程通信,例如在Android应用程序中,可以使用AIDL(Android Interface Definition Language)定义接口和方法,并使用Binder机制在客户端进程和服务端进程之间进行通信。
这样可以提高应用程序的性能和响应速度。
需要注意的是,使用Binder进行进程间通信需要在应用程序开发中进行特殊设计和配置,而且Binder通信也可能存在性能和安全性的问题。
因此,在实际开发中需要谨慎考虑使用场景和限制条件。
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机制原理。
Binder机制是Android系统中的一种进程间通信(IPC)方式,它允许不同进程之间进行数据交换和通信。
在Android系统中,各个应用程序运行在自己的进程中,它们需要进行数据共享和通信,而Binder机制就是为了解决这个问题而设计的。
Binder机制的原理可以简单概括为,Binder驱动程序、Binder通信线程和Binder通信的数据结构。
在Android系统中,Binder驱动程序负责管理Binder通信,它将用户空间的Binder通信请求转发到内核空间,并在内核空间中完成通信操作。
Binder通信线程则是在用户空间和内核空间之间进行通信的桥梁,它负责将用户空间的通信请求传递给Binder驱动程序,并将内核空间的通信结果返回给用户空间。
而Binder通信的数据结构则是用来传递和存储通信数据的,它包括Binder引用、Binder节点和Binder死亡通知等。
在Android系统中,每个进程都有一个Binder驱动程序和一个Binder通信线程,它们负责处理进程内部的Binder通信。
当一个进程需要和另一个进程进行通信时,它会通过Binder驱动程序向目标进程发送一个Binder引用,目标进程接收到Binder引用后,就可以通过Binder通信线程和目标进程进行通信。
这样,就实现了不同进程之间的数据共享和通信。
Binder机制的原理虽然看起来比较复杂,但在实际使用中,开发者只需要使用Android提供的Binder API就可以轻松实现进程间通信。
Android系统已经封装了Binder机制的底层实现,开发者只需要关注业务逻辑即可。
在Android开发中,常用的Binder通信方式包括AIDL(Android Interface Definition Language)和Messenger等,它们都是基于Binder机制实现的。
总的来说,Binder机制是Android系统中非常重要的一部分,它为不同进程之间的数据共享和通信提供了良好的解决方案。
binder 原理Binder是Android系统中的一种进程间通信(IPC)机制,用于不同进程间的对象调用和数据传输。
Binder的原理主要包括以下几个部分:1. Binder驱动:Binder驱动是Linux内核中的一部分,它提供了底层的IPC支持。
每个进程都可以通过特殊文件/dev/binder与驱动进行通信。
2. Binder机制:Binder机制通过三个重要的组件来实现进程间通信,分别是ServiceManager、Binder驱动和Binder通信框架。
- ServiceManager:ServiceManager是Binder的管理服务。
它保持对每个注册的“服务”对象的引用,并通过指定的接口名称提供对这些服务对象的访问。
- Binder驱动:Binder驱动负责处理底层的IPC通信,包括进程间的消息传递和对象的引用传递。
Binder驱动通过Binder节点(Binder Node)维护了一个全局的对象引用表,每个Binder对象都有一个唯一的Binder引用。
- Binder通信框架:Binder通信框架运行在用户态,负责进程间的通信,包括进程之间的消息传递、对象的引用传递等。
它提供了一些基本的类,如Binder、IBinder、BinderProxy等,用于实现跨进程调用、远程对象引用等功能。
3. Binder对象:在Binder机制中,对象是通过Binder对象来实现的。
每个Binder对象都实现了IBinder接口,IBinder接口定义了一些基本的操作,如查询Binder引用、跨进程调用等。
4. 跨进程调用过程:当一个进程需要调用另一个进程中的对象时,它首先从ServiceManager查询目标对象的引用。
然后,它将调用请求以消息的形式发送给目标进程。
在目标进程中,Binder驱动接收到消息后,将消息交给Binder通信框架处理。
Binder通信框架通过查询全局的对象引用表,找到目标对象并调用相应的方法。
binder线程池工作原理Binder线程池是Android中用于处理跨进程通信(IPC)的一种机制,它的工作原理是通过维护一个线程池来处理跨进程通信的请求。
在本文中,我们将深入探讨Binder线程池的工作原理以及它在Android系统中的应用。
我们需要了解Binder的基本概念。
Binder是Android中的一种IPC 机制,它允许不同进程间进行通信。
在Android系统中,每个进程都有一个Binder驱动,它负责处理进程间通信的请求。
当一个进程需要与另一个进程进行通信时,它会通过Binder驱动发送请求,并等待对方进程的响应。
在Android系统中,每个进程都有一个Binder线程池,它用于处理进程间通信的请求。
当一个进程接收到一个跨进程通信的请求时,它会将该请求放入自己的Binder线程池中,并由线程池中的一个线程来处理该请求。
Binder线程池的工作原理如下:当一个进程接收到一个跨进程通信的请求时,它首先会判断当前是否有空闲的线程可以处理该请求。
如果有空闲的线程,则将该请求交给空闲线程处理;如果没有空闲的线程,则会根据一定的策略创建一个新的线程来处理该请求。
在处理请求时,Binder线程池会先检查请求的类型。
如果是一个耗时的操作,比如读取大量数据,线程池会将该请求放入一个专门处理耗时操作的线程中。
这样可以避免耗时操作对其他请求的影响。
如果是一个简单的操作,线程池会将该请求放入一个普通的线程中处理。
Binder线程池还会维护一个请求队列,用于存放等待处理的请求。
当所有线程都在处理其他请求时,新的请求会被放入请求队列中,等待线程池有空闲的线程时再进行处理。
需要注意的是,Binder线程池的大小是有限的。
在Android系统中,默认情况下,每个进程的Binder线程池大小为16。
这是因为线程的创建和销毁都需要消耗一定的系统资源,如果线程池过大,会导致系统资源的浪费。
因此,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 原理AndroidBinder是一种IPC机制,是 Android 系统中非常重要的一部分。
它使得不同进程之间可以通过接口来进行通信,实现了进程间的数据传输,从而让应用程序之间可以互相协作。
Android Binder 主要由以下两个部分组成:Binder 驱动和Binder 服务。
Binder 驱动是位于内核空间的模块,它负责管理进程间通信的核心逻辑。
Binder 服务则是位于用户空间的进程,它负责提供接口,允许其他进程通过 Binder 驱动来进行通信。
Android Binder 采用面向对象的方式来实现进程间通信。
每个Binder 服务都有一个唯一的标识符,称为 Binder ID。
其他进程可以通过 Binder ID 来访问对应的 Binder 服务。
在 Binder 服务中,会定义一些接口,用于提供数据传输和方法调用的功能。
Binder 服务通过 Binder 驱动来进行注册和管理,当其他进程需要访问该服务时,Binder 驱动会将请求传递给对应的 Binder 服务。
Android Binder 采用了一些特殊的机制来实现进程间通信的安全性和效率。
例如,Binder 驱动会对传输的数据进行序列化和反序列化,以确保数据的正确性和一致性。
此外,Binder 驱动还实现了优化机制,能够对频繁的数据传输进行加速,提高传输效率。
总的来说,Android Binder 是 Android 系统中非常重要的一部分。
它实现了进程间通信的功能,让应用程序之间可以互相协作。
对于 Android 开发者来说,理解 Android Binder 的原理,能够更好地进行应用程序的开发和优化。
初探Android中的binder机制Binder机制是Android系统中最主要的进程间通信机制。
虽然Android底层使用的是linux内核,但是除了匿名管道,socket外,Android并没有使用linux 中的命名管道,信号量,消息队列等传统的IPC通信方式。
Binder犹如一张大网,将Android整个系统中的组件,跨进程的组织在一起。
淡化进程,强化组件是Android的一个设计理念。
在这个过程中,Binder发挥了巨大作用。
binder 的作用binder的作用可以概括为两点:IPC:是一种跨进程通信手段,但是传输数据的大小受限制,不建议传输较大数据。
RPC:是一种远程过程调用手段,即一个进程中可以透明的调用另外一个进程中的方法。
两者经常相互伴随,例如跨进程调用的时候,参数的传递以及结果的传递等。
binder机制简述binder实体对象:就是binder服务的提供者,一个提供binder服务的类必须继承BBinder类(native层),因此binder实体对象又叫做BBinder对象。
binder引用对象:是binder服务提供者在客户端进程的代表,每个引用对象类型必须继承BpBinder类(native层),因此binder引用对象有叫做BpBinder对象。
binder代理对象:代理对象简单理解为内聚了一个binder引用对象,因此可以通过这个内聚的引用对象发起RPC调用。
可以有多个不同的代理对象,但却内聚了同一个引用对象。
IBinder对象:BBinder和BpBinder都是继承自IBinder.因此binder实体对象和binder引用对象都可以称为IBinder对象。
可以通过IBinder.queryLocalInterface()方法来判断到底是binder实体对象还是binder引用对象。
binder跨进程传输的数据类型是Parcel。
以RPC为例的示意图如下:android_binder-1.png通过一个运行在内核空间的binder驱动进程,将两个用户空间的进程联系了起来。
Android深入浅出之Binder机制一说明Android系统最常见也是初学者最难搞明白的就是Binder了,很多很多的Service就是通过Binder机制来和客户端通讯交互的。
所以搞明白Binder的话,在很大程度上就能理解程序运行的流程。
我们这里将以MediaService的例子来分析Binder的使用:●ServiceManager,这是Android OS的整个服务的管理程序●MediaService,这个程序里边注册了提供媒体播放的服务程序MediaPlayerService,我们最后只分析这个●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。
这么多疑问,看来我们只有一个个函数深入分析了。
不过,这里先简单介绍下sp这个东西。
sp,究竟是smart pointer还是strong pointer呢?其实我后来发现不用太关注这个,就把它当做一个普通的指针看待,即sp<IServiceManager>======》IServiceManager*吧。
sp是google搞出来的为了方便C/C++程序员管理指针的分配和释放的一套方法,类似JAVA 的什么WeakReference之类的。
我个人觉得,要是自己写程序的话,不用这个东西也成。
好了,以后的分析中,sp<XXX>就看成是XXX*就可以了。
2.1 ProcessState第一个调用的函数是ProcessState::self(),然后赋值给了proc变量,程序运行完,proc会自动delete内部的内容,所以就自动释放了先前分配的资源。
ProcessState位置在framework\base\libs\binder\ProcessState.cppsp<ProcessState> ProcessState::self(){if (gProcess != NULL) return gProcess;---->第一次进来肯定不走这儿AutoMutex _l(gProcessMutex);--->锁保护if (gProcess == NULL) gProcess = new ProcessState;--->创建一个ProcessState 对象return gProcess;--->看见没,这里返回的是指针,但是函数返回的是sp<xxx>,所以//把sp<xxx>看成是XXX*是可以的}再来看看ProcessState构造函数//这个构造函数看来很重要ProcessState::ProcessState(): mDriverFD(open_driver())----->Android很多代码都是这么写的,稍不留神就没看见这里调用了一个很重要的函数, mVMStart(MAP_FAILED)//映射内存的起始地址, mManagesContexts(false), mBinderContextCheckFunc(NULL), mBinderContextUserData(NULL), mThreadPoolStarted(false), mThreadPoolSeq(1){if (mDriverFD >= 0) {//BIDNER_VM_SIZE定义为(1*1024*1024) - (4096 *2) 1M-8KmVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE,mDriverFD, 0);//这个需要你自己去man mmap的用法了,不过大概意思就是//将fd映射为内存,这样内存的memcpy等操作就相当于write/read(fd)了}...}最讨厌这种在构造list中添加函数的写法了,常常疏忽某个变量的初始化是一个函数调用的结果。
open_driver,就是打开/dev/binder这个设备,这个是android在内核中搞的一个专门用于完成进程间通讯而设置的一个虚拟的设备。
BTW,说白了就是内核的提供的一个机制,这个和我们用socket加NET_LINK方式和内核通讯是一个道理。
static int open_driver(){int fd = open("/dev/binder", O_RDWR);//打开/dev/binderif (fd >= 0) {....size_t maxThreads = 15;//通过ioctl方式告诉内核,这个fd支持最大线程数是15个。
result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads); } return fd;好了,到这里Process::self就分析完了,到底干什么了呢?●打开/dev/binder设备,这样的话就相当于和内核binder机制有了交互的通道●映射fd到内存,设备的fd传进去后,估计这块内存是和binder设备共享的接下来,就到调用defaultServiceManager()地方了。
2.2 defaultServiceManagerdefaultServiceManager位置在framework\base\libs\binder\IServiceManager.cpp中sp<IServiceManager> defaultServiceManager(){if (gDefaultServiceManager != NULL) return gDefaultServiceManager;//又是一个单例,设计模式中叫 singleton。
{AutoMutex _l(gDefaultServiceManagerLock);if (gDefaultServiceManager == NULL) {//真正的gDefaultServiceManager是在这里创建的喔gDefaultServiceManager = interface_cast<IServiceManager>(ProcessState::self()->getContextObject(NULL));}}return gDefaultServiceManager;}-----》gDefaultServiceManager = interface_cast<IServiceManager>(ProcessState::self()->getContextObject(NULL));ProcessState::self,肯定返回的是刚才创建的gProcess,然后调用它的getContextObject,注意,传进去的是NULL,即0//回到ProcessState类,sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& caller){if (supportsProcesses()) {//该函数根据打开设备是否成功来判断是否支持process,//在真机上肯定走这个return getStrongProxyForHandle(0);//注意,这里传入0}}----》进入到getStrongProxyForHandle,函数名字怪怪的,经常严重阻碍大脑运转//注意这个参数的命名,handle。
搞过windows的应该比较熟悉这个名字,这是对//资源的一种标示,其实说白了就是某个数据结构,保存在数组中,然后handle是它在这个数组中的索引。
--->就是这么一个玩意儿sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle){sp<IBinder> result;AutoMutex _l(mLock);handle_entry* e = lookupHandleLocked(handle);--》哈哈,果然,从数组中查找对应索引的资源,lookupHandleLocked这个就不说了,内部会返回一个handle_entry下面是 handle_entry 的结构/*struct handle_entry {IBinder* binder;--->BinderRefBase::weakref_type* refs;-->不知道是什么,不影响.};*/if (e != NULL) {IBinder* b = e->binder; -->第一次进来,肯定为空if (b == NULL || !e->refs->attemptIncWeak(this)) {b = new BpBinder(handle); --->看见了吧,创建了一个新的BpBindere->binder = b;result = b;}....}return result; 返回刚才创建的BpBinder。