android 进程间通讯---bind的前世

在分析bind机制以前,我发现已经有一篇文章讲解的很是清晰,而且提出了不少问题。java

地址:http://my.oschina.net/keeponmoving/blog/64218linux

 

一.Linux系统进程间通讯有哪些方式?
    1.socket; 2.name pipe命名管道; 3.message queue消息队列; 4.singal信号量; 5.share memory共享内存;
二.Java系统的通讯方式是什么? 1.socket; 2.name pipe;
三.Android系统通讯方式是什么? Binder 通讯;
四.Binder通讯的优点是什么? 高效率
五.Binder通讯的特色是什么? 是同步,而不是异步;
六.Binder通讯是如何实现的?
   1.Binder通讯是经过linux的binder driver来实现的,
   2.Binder通讯操做相似线程迁移(thread migration),两个进程间IPC看起来就象是一个进程进入另外一个进程执行代码而后带着执行的结果返回;
   3.Binder的用户空间为每个进程维护着一个可用的线程池,线程池用于处理到来的IPC以及执行进程本地消息,Binder通讯是同步而不是异步。
七. Android中的 Binder通讯实现要点:
   1. Android中的Binder通讯是基于Service与Client的工做模型的;
   2. 全部须要IBinder通讯的进程都必须建立一个IBinder接口;
   3. 系统中有一个进程管理全部的system service:
   4. Android不容许用户添加非受权的System service;
   5. 如今源码开放了,咱们能够修改一些代码来实现添加底层system Service的目的;
   6. 对用户程序来讲,咱们也要建立server,或者Service用于进程间通讯;
   7. ActivityManagerService管理JAVA应用层全部的service建立与链接(connect),disconnect;
   8. 全部的Activity也是经过这个service来启动,加载的;
   9. ActivityManagerService也是加载在Systems Servcie中的;
八.Android的 Service工做流程
  1.Android虚拟机启动以前系统会先启动service Manager进程;
  2.service Manager打开binder驱动,并通知binder kernel驱动程序这个进程将做为System Service Manager;
  3.而后该进程将进入一个循环,等待处理来自其余进程的数据。
  4.用户建立一个System service后,经过defaultServiceManager获得一个远程ServiceManager的接口,经过这个接口咱们能够调用addService函数将System service添加到Service Manager进程中;
  5.而后client能够经过getService获取到须要链接的目的Service的IBinder对象,这个IBinder是Service的BBinder在binder kernel的一个参考,
  6.因此service IBinder 在binder kernel中不会存在相同的两个IBinder对象,每个Client进程一样须要打开Binder驱动程序。对用户程序而言,咱们得到这个对象就能够经过binder kernel访问service对象中的方法。
  7.Client与Service在不一样的进程中,经过这种方式实现了相似线程间的迁移的通讯方式,对用户程序而言当调用Service返回的IBinder接口后,访问Service中的方法就如同调用本身的函数。
 

以下是详细说明Binder。android

 

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返回数据,收到数据后,继续本身的工做。app

  binder的框架能够分红3层,框架

  最下层是linux os和binder driver。binder driver本质上是进程间的共享内存,各进程将要发送到其它进程的数据写入到driver,从driver读取其它进程发送来的数据。异步

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

  其实到中间层,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。

相关文章
相关标签/搜索