Android 对进程间通信实现了一套轻量级的IPC机制 --- Binder机制,基于此基础之上提供了整体的封装,从而实现对象代理机制。【这与COM, CORBA有相似之处,即都是基于对象代理机制。不过android似乎只限制在本机内,而不象前者是可以跨网络的】

Binder工作模式

1、客户端通过某种方式(后文会详细介绍)得到服务器端的代理对象。从客户端角度看来代理对象和他的本地对象没有什么差别。它可以像其他本地对象一样调用其方法,访问其变量。
2、客户端通过调用服务器代理对象的方法向服务器端发送请求。
3、代理对象把用户请求通过Android内核(Linux内核)的Binder驱动发送到服务器进程。
4、服务器进程处理用户请求,并通过Android内核(Linux内核)的Binder驱动返回处理结果给客户端的服务器代理对象。
5、客户端收到服务器端的返回结果。

Bider机制的组成

1.Binder驱动

/dev/binder 是Android内核的一个字符驱动设备,它是IPC的核心部分。客户端发送请求最终就是通过它来传递到服务端,而服务端的返回结果也是通过它来传给客户端。内核源码:binder.c

2.Service Manager

顾名思义,它是负责管理服务。服务端有服务的话就得向它注册,而客户端需要向它查询、获得服务。

3.提供服务的Server (Service)

提供服务的Server, 对普通的应用开发来讲,咱们用到的就是Service, 具体的工作Android都帮忙做了封装,所以开发变得很容易。

4.调用对象代理的Client (Activity)

普通的应用开发来讲就是 Activity 通过代理对象去请求调用服务,注意:这个过程是同步的,所以如果估计这个服务调用很耗时,那么需要考虑启新线程来调用,而不能用UI主线程。

5.代理对象 (底层:BpBinder)

底层代理对象工作机制:客户端进程通过服务代理BpBinder对象,调用transact函数,该函数作用就是把客户端的请求写入binder设备另一端的Service进程。从JAVA层面来讲,Android已经为我们封装定义了IBinder接口.

Note: 服务端Service,从底层来讲(c++)都是继承自BBinder (BBinder继承自IBinder接口),因此Service在底层需要改写BBinder的onTransact虚函数,这样当客户端请求service时,框架会调用相应的ServiceonTransact函数。 对于JAVA层面来讲,实现Service时只需要实现AIDL定义的Stub接口就好,底层的细节系统都为咱们封装好,无需我们的关注。所以说Android的封装还是做的很好!

以上基本概念为转载:

http://galin.blog.sohu.com/170975867.html

以下为自己的学习笔记:

进程通信:

在Android中,每个应用程序都有自己的进程,当需要在不同的进程之间传递对象时,该如何实现呢?显然, Java中是不支持跨进程内存共享的。因此要传递对象,需要把对象解析成操作系统能够理解的数据格式,以达到跨界对象访问的目的。在JavaEE中,采用RMI通过序列化传递对象。在Android中,则采用AIDL(Android InterfaceDefinition Language:接口定义语言)方式实现。

AIDL是一种接口定义语言用于约束两个进程间的通讯规则,供编译器生成代码,实现Android设备上的两个进程间通信(IPC)。AIDL的IPC机制和EJB所采用的CORBA很类似,进程之间的通信信息,首先会被转换成AIDL协议消息,然后发送给对方,对方收到AIDL协议消息后再转换成相应的对象。由于进程之间的通信信息需要双向转换,所以android采用代理类在背后实现了信息的双向转换,代理类由android编译器生成,对开发人员来说是透明的。

使用AIDL实现进程间通信的步骤:

以A应用(访问者)client从B应用(远程服务提供者)RemoteService中查询对应学号的学生的姓名的例子为例:

1.远程服务应用中:

远程服务端,也就是RemoteService应用中,在src下某个包中创建一个处理业务的接口类,如下:

e:接口定义语言)方式实现。

AIDL是一种接口定义语言用于约束两个进程间的通讯规则,供编译器生成代码,实现Android设备上的两个进程间通信(IPC)。AIDL的IPC机制和EJB所采用的CORBA很类似,进程之间的通信信息,首先会被转换成AIDL协议消息,然后发送给对方,对方收到AIDL协议消息后再转换成相应的对象。由于进程之间的通信信息需要双向转换,所以android采用代理类在背后实现了信息的双向转换,代理类由android编译器生成,对开发人员来说是透明的。

使用AIDL实现进程间通信的步骤:

以A应用(访问者)client从B应用(远程服务提供者)RemoteService中查询对应学号的学生的姓名的例子为例:

1.远程服务应用中:

远程服务端,也就是RemoteService应用中,在src下某个包中创建一个处理业务的接口类,如下:


然后,根据后面注意事项中的规则,将接口的代码做一些处理,变成如下:

然后,将相应的接口文件的后缀名改为“ .aidl”,然后,刷新,则系统会在gen目录下生成一个Java文件,会用到这个Java文件中的类及其内部类。(注意:如果项目中还有有错误的地方,系统则无法根据AIDL生成Java代码。)

远程服务的类文件如下:其中,红色框框住的部分,是来自于系统根据AIDL生成的Java类的一个内部类,远程服务的onBind方法返回的IBinder对象,必须是该类(IstudentService.Stub)的子类的对象。



2.访问者的应用中:

将远程服务端的aidl文件拷贝到访问者的应用中(src目录下),然后,访问者端代码如下:



访问者代码中,访问者端拿到的IBinder对象不能(像访问者与本地服务通信那样)强制类型转换,需要通过如下方法进行类型转换。

binder = StudentService.Stub.asInterface(service);

进程间通信的时候,访问者获得的对象,也并不是远程服务onBind方法中返回的原始的对象,而是那个对象的代理对象,操作系统在代理中做了协议转换的事情,对开发者是透明的。(隐藏一些细节的时候,一般都是通过代理对象来做。)

进程间通过AIDL通信的注意事项:

1.AIDL文件的书写规则:

编写Aidl文件时,需要注意下面几点:

1.接口名和aidl文件名相同。

2.接口和方法前不用加访问权限修饰符public,private,protected等,也不能用final,static。

3.Aidl默认支持的类型包话java基本类型(int、long、boolean等)和(String、List、Map、CharSequence),使用这些类型时不需要import声明。对于List和Map中的元素类型必须是Aidl支持的类型。如果使用自定义类型作为参数或返回值,自定义类型必须实现Parcelable接口。

4.自定义类型和AIDL生成的其它接口类型在aidl描述文件中,应该显式import,即便在该类和定义的包在同一个包中。

5.在aidl文件中所有非Java基本类型参数必须加上in、out、inout标记,以指明参数是输入参数、输出参数还是输入输出参数。

6.Java原始类型默认的标记为in,不能为其它标记。

http://blog.csdn.net/android_tutor/article/category/656416

更多相关文章

  1. Android之WebView优化之路
  2. 避免Android中Context引起的内存泄露
  3. Android(安卓)内存优化
  4. 图解Android中的Binder机制
  5. android使用html开发软件界面
  6. Android中的AIDL
  7. android 内存管理
  8. android进程间服务通信示例
  9. Android内核详解之Low memory killer

随机推荐

  1. Android(安卓)编程下 Touch 事件的分发和
  2. Android自动检测版本及自动升级
  3. Android(安卓)中文 API (90) —— Window
  4. Android各版本 内外卡真实路径
  5. Android基础类之BaseAdapter
  6. Android(安卓)实时视频采集/编码/传输/解
  7. [Android] 一份代码,两个版本
  8. Android开发实战三之导入现有Android工程
  9. Android设置透明、半透明等效果
  10. Android(安卓)隐藏手机号中间四位和隐藏