binder

Android110221:Android binder,parcel和service的简记 (2)
概述


Email:    zcatt@163.com
Blog    http://zcatt.cublog.cn
 
内容提要
文档简要整理binder,parcel,和service的内容。以供备忘和参考。

声明
仅限学习交流,禁止商业用途。转载需注明出处。

版本记录
Date        Ver        Note
2011-02-21    0.1        Draft.  zcatt, Beijing
 

1. binder的结构

  binder是解决ipc和rpc的工具。android使用的是linux os,支持多进程和多线程。同时,对于java app,一个vm占用一个进程。做为完善的开发框架,android必须支持ipc。binder就是解决ipc问题的途径,更进一步,binde还支持rpc。

  进程有自己的地址空间,不同进程间的通信并不能直接引用地址。一般的解决途径是,发送进程把需要传送的数据按照一定格式(marshall)转换成二进制形式/特定格式的数据,发往接收进程;接收进程收到二进制形式、特定格式的数据后,反转换(unmarshall)成原文数据,然后使用。binder使用的就是这种步骤。

  binder使用的是同步c/s模型,s循环阻塞在接收数据操作上,随时处理c的数据,处理后发送回c;c则将请求服务的数据发送到s,阻塞在收取s返回数据,收到数据后,继续自己的工作。

  binder的框架可以分成3层,如图<binder arch>。
 
  最下层是linux os和binder driver。binder driver本质上是进程间的共享内存,各进程将要发送到其它进程的数据写入到driver,从driver读取其它进程发送来的数据。

  中间层是cpp实现的framework,完成数据的接收发送转换,和c/s流程的支持。

  其实到中间层,binder的架构就已经完全具备了。但android使用的是java做为一般app的开发语言。所以还需要jni和相应java binder类的支持,这就是中间层上面的第三层:jni/java

  假设c,s都是java实现,app ipc一般的情景是这样的, app client 收集ipc的数据,穿过jni,加工下传,经framework,写入driver。数据经driver上传,反加工经framework,穿过jni,上传到app server。

  对于rpc的支持,需要一点点技巧,直接传递函数指针是无法使用的。为了是叙述的方便,先澄清一对概念:本地local和远端remote。定义rpc函数的进程称作本地,调用rpc函数的进程称作远端。rpc的实现实际上是远端定义一个rpc的proxy,远端将proxy想做rpc在本地的实现,貌似本地函数操作一般使用。而这个proxy实际上仅仅是将自己登记在本地的handle和入口参数发送本地,本地根据handle,知晓是哪个远端进程的proxy,调用函数,给定入口参数,执行完毕后,将出口参数再返回远端的proxy(因为我们有handle了)。binder的实现中handle和本地函数的对应关系是保存在driver中管理的。


2. binder driver

  binder driver是binder机制的基础,是实现ipc的通道。

  binder driver与framework和app的功能操作是用ioctl方式实现的。最基本的操作是数据读写操作。一次读写操作有两个子操作组成:写子操作和读子操作。driver为每个进程和线程维护了一个数据结构,其中有一个list,挂接了其它进程写入的数据,还有一个信号量。写子操作负责将数据挂接到接收进程对应数据结构的list上。读子操作负责处理自己进程中list上的数据,传回framework和app。

  binder driver的第二个功能是为了支持rpc,就是维护本地函数和远端proxy的handle之间的对应关系。更复杂的是维护两个远端Proxy的handle之间的对应关系,这两个proxy是同一rpc的proxy。

3. binder framework


  binder的framework是cpp实现的,这里分成本地local/s和远端remote/c两半来描述。
 
  公共类IBinder派生出两个子类,BBinder用于local,BpBinder用于remote。

  本地实现的类以BBinder为基类派生,接收数据后,处理,并将结构发会远端。

  远端proxy的类使用BpBinder,接收和发送数据到本地。

  进一步方便开发,引入了IInterface类,开发者从Interface派生子类,定义自己需要的rpc操作。
 
  在IInterface的装饰下,从BBinder派生出了本地的关键类 BnInterface<INTERFACE>;从BpRefBase派生出了包含成员BpBinder对象的远端关键类BpInterface<INTERFACE>。

  于是,创世纪中,神说:‘要有光’,就有了光。神看光是好的,就把光暗分开了。 神称光为昼,称暗为夜。有晚上,有早晨,这是头一日。

4. binder jni,java类和aidl工具

  binder framework的机制要被java使用,需要经过包装。除了jni相关部分,android在java中还定义了几个相关的接口和类,IBinder,Binder,BinderProxy,IInterface,BinderInternal。

  aidl工具则是方便java实现c/s结构的一个工具,开发者编写简单的接口描述idl文件,则aidl自动生成local和remote的Binder类。让开发者关注在实际的功能开发上,不必为binder机制耗费无谓的精力。



5. parcel是什么

  为了便于ipc之间传递的数据的操作,binder引入了parcel的概念。parcel可以想成快递公司的包装箱,需要传递的各种类型的数据都被打包进parcel类,binder负责传递parcel对象,接收端则从parcel解出数据。这样的机制即减少了各种数据类型对传递的复杂性,又可以通过增加打包/解包parcel的数据类型,轻易实现扩展。
  parcel已经支持容纳基本数据类型和一些复合数据类型。
  在framework层面,parcel提供了Flattenable基类,可以扩展parcel容纳的数据类型。
  在java parcel层面,parcel提供了Parcelable接口,可以扩展parcel容纳的数据类型。


6. 依赖于binder的service
 
  ipc/rpc已经被binder机制解决掉了,那么service面临的唯一问题就是service如何让想使用service的client招到service。解决的方案就是 service manager。service manager是一个特殊进程,每个service都会注册登记到service manager中,而client可以从service manager查询得到自己需要使用的service。
Locations of visitors to this page

<think>好的,我现在需要回答用户关于Android Binder的问题。首先,用户提到想了解操作系统中的Binder,特别是Android中的Binder。我需要先回忆一下Binder的基本概念和作用,然后结合提供的引用内容来组织回答。 根据用户提供的引用[1],Binder是Android用于进程间通信(IPC)的机制,基于内核内存引用,专为移动设备优化。这应该是回答的核心点。我需要解释Binder的作用、工作原理以及它的优势。 接下来,引用[1]提到Android的组件模型是基于进程的,系统功能作为服务进程运行。因此,Binder在这里的作用是连接这些进程,实现跨进程通信。我需要强调Binder在组件间通信中的重要性,比如Activity、Service等如何通过Binder系统服务交互。 引用[3]提到了Linux内核配置中的SELinux设置,虽然和Binder没有直接关联,但可能涉及到安全性。不过用户的问题中没有提到安全方面,所以可能不需要深入这部分。不过可以提一下Binder的安全机制,比如引用[2]中的安全库可能相关,但需要确认是否直接相关。 引用[4]介绍了proc文件系统,这通常用于访问内核数据结构。虽然Binder可能在内核中有相关实现,但用户的问题更多关注Binder的功能而非底层实现细节。不过可以简要提到Binder驱动在Linux内核中的位置,说明其底层依赖。 接下来,我需要确保回答结构清晰,分点解释。可能的结构包括:Binder的定义、核心功能、工作原理、优势、应用场景。同时,用户示例中的相关问题部分需要生成相关问题,例如Binder其他IPC机制的对比,如何实现Binder通信,性能优化等。 需要检查是否有遗漏的信息。例如,用户引用中提到的Binder使用内核内存引用,这可能涉及到共享内存机制,减少数据拷贝,从而提升性能。这一点需要详细说明,因为这是Binder优化的关键。 另外,可能需要解释Binder的架构,比如Client-Server模型,以及Binder驱动在其中的角色。引用[1]中提到系统功能作为服务进程,客户端通过Binder调用服务,这符合C/S模型。 还需要注意用户不可见的系统级指令,如数学表达式用$...$,但这个问题可能不涉及数学公式,所以可能不需要处理这部分。但需要确保回答中的技术术语正确,比如正确的命名和机制描述。 最后,生成的相关问题需要围绕Binder的扩展知识,比如其他IPC的对比、具体实现细节、性能分析、安全机制等。需要确保问题有针对性,帮助用户进一步探索。</think>### Android Binder 详解 **Binder** 是 Android 系统中**进程间通信(IPC)**的核心机制,基于 Linux 内核实现,专为移动设备的高效性和低资源消耗优化[^1]。其核心功能是支持跨进程的组件交互(如 Activity、Service 系统服务通信),并通过**内核内存共享**减少数据拷贝,提升性能。 #### 核心特性工作原理 1. **进程隔离通信** Android 应用默认运行在独立进程中,Binder 允许这些进程安全地调用系统服务(如位置、传感器)或其他应用的组件。例如,应用通过 `bindService()` 绑定服务时,Binder 负责跨进程传递请求和结果。 2. **内核驱动层** Binder 在内核中实现为**字符设备驱动**(`/dev/binder`),管理进程间的内存映射通信队列。数据通过**内存映射(mmap)**直接在发送方和接收方的用户空间共享,避免多次拷贝。 3. **组件化支持** Android 的四大组件(Activity、Service 等)依赖 Binder 实现生命周期管理跨进程调用。例如,启动一个其他应用的 Activity 时,系统服务 `ActivityManagerService` 通过 Binder 协调进程间通信。 4. **安全性** Binder 通信基于进程的 UID/PID 进行身份验证,并 SELinux 策略集成(如引用[3]中提到的 `androidboot.selinux` 配置),确保只有授权进程可访问特定服务[^3]。 #### 性能优势 - **零拷贝传输**:通过内核内存映射,数据直接在通信双方的用户空间共享,减少传统 IPC 中内核缓冲区的中转开销。 - **线程池管理**:Binder 驱动自动分配线程处理请求,避免阻塞主线程。 - **轻量级序列化**:使用 Parcel 对象进行高效数据封装,支持基本类型和 Binder 对象引用。 #### 代码示例:Binder 调用流程 ```java // 服务端定义 AIDL 接口 interface IMyService { int calculate(int a, intBinder机制); } // 客户端绑定服务并调用 IMyService service = IMyService.Stub.asInterface(binder); int result = service.calculate(10, 20); ``` #### 其他 IPC 的对比 | 机制 | 性能 | 复杂度 | 适用场景 | |-------------|--------|--------|-----------------------| | Binder | 高 | 低 | 高频跨进程调用 | | Socket | 中 | 高 | 网络或跨设备通信 | | 共享内存 | 极高 | 高 | 大数据量低延迟 |
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值