android binder通信里用 C 语言编写的应用程序怎么通过 binder 节点通信?

文章来自 Android技术内幕 系统卷
什么是IPC机制以及IPC机制的种类
在Linux中,是以进程为单位分配和管理资源的。出于保护机制,一个进程不能直接访问另一个进程的资源,也就是说,进程之间互相封闭。但是,一个复杂的应用系统中,通常会使用多个相关的进程来共同完成一项任务,因此要求进程之间必须能够互相通信,从而共享资源和信息。所以,操作系统内核必须提供进程间的通信机制(IPC)。
IPC机制种类:采用命名管道(name pipe),消息队列(message queue),信号(signal),内存共享(share memory);
在Android终端上的应用软件的通信几乎看不到这些IPC通信方式,取而代之的是Binder方式。
Binder更简洁和快速,消耗的内存资源更小,Binder主要提供以下一些功能:
用驱动程序来推进进程间的通信。
通过共享内存来提高性能
为进程请求分配每个进程的线程池
针对系统中的对象引入了引用计数和跨进程的对象引用映射
进程间的同步调用
初识Binder
Binder是通过Linux的Binder Driver 来实现的,Binder操作类似于线程迁移(Thread migration),两个进程间通信看起来就像是一个进程进入另一个进程去执行代码,然后带着执行的结果返回。同时Binder机制是基于OpenBinder来实现的,是一个OpenBinder的Linux实现,android系统的运行都是将依赖Binder驱动。(OpenBinder组件架构是一个系统,主要提供一个高层抽象上传统的现代操作系统服务。当前实现运行在Linux,但是代码运行在一个不同的平台。) Binder的驱动原理 为了完成进程间通信,Binder采用了AIDL (Android Interface Definition Language)来描述进程间的接口。在实际的实现中,Binder是作为一个特殊的字符型设备而存在的,设备节点为/dev/binder,其实现遵循Linux设备驱动模型,实现代码主要涉及以下文件:
kernel/driver/staging/binder.h
kernel/driver/staging/binder.c
Binder1驱动的实现
上面我们已经对Binder驱动的原理进行了分析,在开始分析驱动的实现之前,我们还是通过一个例子说明Binder在实际应用中应该如何运用,以及它能帮我们解决什么样的问题。比如:A进程如果要使用B进程的服务,B进程首先要注册此服务,A进程通过Binder获取该服务的handle,通过这个handle ,A进程就可以使用该服务了,此外,你可以把handle理解成地址。A进程使用B进程的服务还意味着二者遵循相同的协议,这个协议反映在代码上就是二者要实现Ibinder接口。 1.&对象&与&引用& Binder不仅是Android 系统中的一个完善的IPC机制,它也可以被当作Andriod系统的一种RPC(远程过程调用)机制,那么我们就要记住Binder不仅可以与本地进程通信,还可以与远程进程通信;这里的本地进程就是我们所说的本地对象,而远程进程则使我们所说的远程服务的一个&引用&。(&引用&这个词并不是官方所描述的,而是笔者为了方便大家理解,将其称为引用) 那么这个本地&对象&与远程对象的&引用&有什么不同呢? 本地&对象&表示本地进程的地址空间的一个地址,而远程对象的&引用&则是一个抽象的32位句柄。 它们之间的关系是互质的: 所有的进程本地对象都是本地进程的一个地址(address,ptr,binder),所有的远程进程的对象的&引用&都是一个句柄。
Binder的构架与实现
通过前面的学习,我们对Binder的整个工作流程有了一个深入 的认识,关于Binder的实现,还涉及有很多细节。 Binder的系统结构 在Android设计中,每一个Activity都是一个独立的进程,每个service也是一个独立的进程,而Activity要与Service进行通信,就是跨进程的通信,这时就需要使用Binder机制了。 那么在这里可以把Activity看作客户端,实际上也就是一个客户端与服务端之间的通信。 1.Binder机制的组成 Android的Binder机制就是一个C/S构架,客户端和服务端直接通过Binder交互数据,打开Binder写入数据,通过Binder读取数据,这样通讯就可以完成了。关于数据的读写则是由Binder的驱动完成的,除了Binder的驱动之外,整个机制还包括以下几个组成部分: (1)Serice Manager Serice Manager主要负责管理Android系统中所有的服务,当客户端要与服务端进行通信时,首先就会通过Service Manager来查询和取得所需要交互的服务。当然,每个服务也都需要向service Manager注册自己提供的服务,以便能够提供客户端进行查询和获取。
(2)服务(server) 这里的服务即上面所说的服务端,通常也是Android的系统服务,通过Service Manager可以查询和获取某个server。 (3)客户端 这里的客户端一般是指Android系统上面的应用程序。它可以请求Server中的服务,比如Activity。 (4)服务代理 服务代理是指在客户端应用程序中生成的server代理(proxy)。从应用程序的角度来看,代理对象和本地对象没有差别,都可以调用其方法,方法都是同步的,并且返回相应的结果。服务代理也是Binder机制的核心模块。 2.Binder的系统构架 在Android源码中,有关Binder的实现在各个层析都有,主要的Binder库由本地原生代码实现,java和C++层都定义有同样功能的Binder接口,供应用程序使用,它们实际上都是调用原生Binder库的实现。Binder的系统构架如图:
其中,Binder驱动在前面已经介绍,它用于实现Binder的设备驱动,主要负责组织Binder的服务节点,调用Binder相关的处理线程,完成实际的Binder传输等,它位于Binder结构的最底层(即Linux内核层)。Binder Adapter 层是对Binder驱动的封装,主要用于操作Binder驱动,即应用程序不必直接接触Binder驱动程序,实现包括IPCThreadState.cpp 和ProcessState.cpp以及Parcel.cpp,以及Parcel.cpp中的部分内容。Binder核心库是Binder框架的核心实现,主体的客户端/服务端都分别有java和C++两种实现方案,主要供应程序使用,比如摄像头和多媒体等。它们通过Binder的核心库来实现。 Binder的机制和原理 作为Android系统的核心机制,Binder几乎贯穿整个Android系统,本节将从Binder所涉及的service Manager,服务,客户端,服务端(代理对象)等各个部分进行分析,在分析之前首先需要明确Binder的工作流程: (1)客户端首先获得服务器的代理对象。所谓的代理对象实际上就是在客户端建立一个服务端的&引用&,该代理对象具有服务端的功能,使其在客户端访问服务端的方法就像访问本地方法一样。 (2)客户端通过调用服务器代理对象的方式向服务端发送请求。 (3)代理对象将用户请求通过Binder驱动发送到服务器进程。 (4)服务器进程处理用户请求,并通过Binder驱动返回处理结果给客户端的服务器代理对象。 (5)客户端收到服务器端的返回结果。 经过这样一个流程,Binder就完成了一次通信。课可以看出,这里与Binder通信的对象服务端就是服务,下面我们首先分析Android中的服务。
阅读(...) 评论() 上传我的文档
 下载
 收藏
该文档贡献者很忙,什么也没留下。
 下载此文档
正在努力加载中...
Android系统进程间通信Binder机制在应用程序框架层的Java接口源代码分析
下载积分:300
内容提示:Android系统进程间通信Binder机制在应用程序框架层的Java接口源代码分析
文档格式:DOC|
浏览次数:181|
上传日期: 11:36:43|
文档星级:
该用户还上传了这些文档
Android系统进程间通信Binder机制在应用程序框架层的J
官方公共微信零基础理解Binder,理解binder-android100学习网
零基础理解Binder,理解binder
零基础理解Binder,理解binder
写在前面的当一个Android App存在某个不需要UI的后台运行需求时,或者是因为内存占用需要采用多进程方案时,我们免不了与多进程
零基础理解Binder,理解binder
写在前面的
当一个Android App存在某个不需要UI的后台运行需求时,或者是因为内存占用需要采用多进程方案时,我们免不了与多进程打交道。必不可少的,需要考虑Binder在其中如何实现。
最常见的Binder实现当然是AIDL,然而Binder的实现绝不仅仅只有AIDL一种方式,如果止步于写.aidl,那么对于Binder,对于Android整体的跨进程传输过程的理解都只能流于形式。
但是想理解Binder不是一件容易的事情,Binder的概念涉及太多知识点,遍观各大论坛上关于Binder的博客或是文章,作者多半已经默认阅读者具备了必要的学习基础。这对于零基础的同学肿么办,我罗列出了几个自己学习中觉得十分重要的知识点,如果希望能够彻底的理解Binder JAVA层概念,那么务必要明了这些知识点。希望对那些初学者朋友有一定帮助。
AIDL是Android为了在不同进程中实现Binder接口的一套专用接口语言。
在维基百科上对于接口语言的定义是这样的
接口描述语言(Interface description language,缩写IDL),是用来描述软件组件接口的一种计算机语言。IDL通过一种中立的方式来描述接口,使得在不同平台上运行的对象和用不同语言编写的程序可以相互通信交流;比如,一个组件用C++写成,另一个组件用Java写成。
接口语言通常用来描述两种不同对象之间共同一套通信协议,放在Android概念里,一般指的是两个不同进程之间需要通信时必须遵守的一套标准。
Binder的实质仍然是IPC。
通常我们所说的IPC,指的是以某种标准所做的进程间通信过程(inter-process communication)。我们知道,Android的每一个应用可以视作是跑在Davlk虚拟机上的独立进程。而Linux内核出于对进程安全的考虑,要求不同UID/GID的进程不能访问互相访问彼此的资源。因此一般来讲,每个Android应用,或者说每个独立进程的组件都不能像本地方法一样调用其他进程方法。
基于这个原因,Linux内核支持若干种进程间通信机制,为的是在维护进程安全性的同时还能提供针对不同场景的通信手段。而在Android Binder用到的是叫做匿名共享内存(Anonymous Shared Memory)的方式。Binder的实质就是通过这种IPC方式来完成不同进程之间的通信的。
Binder的实现是一个典型的C/S结构。
C/S可以简单的理解为系统为了负载均衡,将一个大任务拆分为多个子任务,并分发给不同的终端结构来处理,以达到减少负荷提高响应速度的目的。在Android的环境中,在分布式系统中,终端结构可以是计算机与服务器,而在Android系统中,则指的是不同的进程实体。理解了C/S结构的一些特征,对Binder的消息握手,传输模式等等行为会有更深刻的理解。
Binder的概念
终于说到了Binder。
对于Binder的解释,最官方的莫过于developerAndroid对于Service使用这一章的说明。如果详细的读过这篇文档,我想大部分人能够对Binder的使用,特别是如何通过AIDL来实现Binder接口的操作,有比较清楚的认识。
但是Binder究竟是什么?它是如何实现的?
这里十分推荐老罗关于Binder学习计划这个系列的文档,对于Binder的整体运行机制有了十分清晰的描述,如果你需要整体全面的理解Binder,那么阅读源代码的同时,这套文档一定可以帮助你很多。
弄清楚以上几个概念后,我们可以开始讨论Binder的实现了。
Binder的实现有很多种,最常见的方式是通过AIDL来实现,相信做过跨进程访问Service的同学也肯定写过.aidl。除此之外,Android还支持通过Message方式和直接继承Binder类的方式来完成Binder实现。
而我要给大家介绍的,就是最后一种方式。
继承Binder类的IBinder接口实现
我以一个最简单的功能为例——控制并打印不同进程的pid,来介绍一个典型的Binder实现过程。
创建项目,并设置多进程运行环境
为了在同一个项目中模拟多进程情形,我将Service组件设置为其他的进程
android:name=".MainActivity"
android:label="@string/app_name" &
&intent-filter&
&action android:name="android.intent.action.MAIN" /&
&category android:name="android.intent.category.LAUNCHER" /&
&/intent-filter&
&/activity&
android:name=".BinderService"
android:process=":other"
android:enabled="true"
android:exported="true" &
&/service&
Activity以及Service表现
在我们的模拟代码中,Activity与Service绑定之后可以在onServiceConnection回调中获取一个Binder实例,通过对这个对象向下转型得到指定Interface的接口对象,从而调用Service中实现的具体的LogService方法。
真实的情况虽然没有所描述的这么简单,但也与之相差不远,流程图如下:
Created with Rapha

我要回帖

更多关于 binder进程间通信机制 的文章

 

随机推荐