原文地址:http://www.apkbus.com/android-83462-1-1.html
Android 进程通信(IPC、AIDL)
什么是IPC?
IPC(Inter-Process Communication,进程间通信)
IPC ( Instruction per Clock 及CPU每一时钟周期内所执行的指令多少) IPC代表了一款处理器的设计架构,一旦该处理器设计完成之后,IPC值就不会再改变了。
1、Android进程内通信
Android为了屏蔽进程的概念,利用不同的组件[Activity、Service 或者其它组件]来表示进程之间的通信。
组件间通信的核心机制是Intent ,通过Intent可以开启一个Activity或Service,
Intent包含两部分:action和category(区分性数据)、data(内容性数据)
Intent类型:
1)显示Intent---直接指定消息的目的地,只适合同一进程内的不同组件之间通信new Intent(this,Target.class)
2)隐式Intent---AndroidMainifest.xml中注册,一般用于跨进程通信new Intent(String action)
3)实现Intent简单进程间通信
重点在于隐式Intent:
a、一个<activity>包括:
零个或多个<intent-filter>
它主要是作为匹配的标准,能否匹配成功由<action>、<category>、<data>三个tag共同决定的。
b、一个<intent-filter>包括:
一个或多个 <action>
零个或多个 <category>
指定<activity>的分类特征
例如:
<category android :name="android.intent.category.LAUNCHER" />
--说明该<activity>是该project运行 的第一个界面
<category android:name="android.intent.category.HOME" />
--说明该<activity>可以作为Launcher的,即系统 操作界面
c、零个或一个 <data>
指定携带的数据的类型,使用MIME类型描述方式来描述
例如:<data android:mimeType="video/mpeg" />
video/mpeg表示编码格式为mpeg的视频 ,
也可以使用通配符video/*表示任意格式的视频文件类型;
4)一个Intent对应多种匹配结果的处理说明
一个intent有多个可匹配的处理组件,系统如何处理?
分响应消息的组件类型:
1)如果是service那么这些service都可以启动并处理消息。
2)如果是Activity则会弹出一个对话框让用户进行选择。
5)安全问题----权限permission
2、IPC机制
Android 对进程间通信实现了一套轻量级的IPC机制 --- Binder机制,基于此基础之上提供了整体的封装,从而实现对象代理机制。
A、什么是Binder工作模式?
1)客户端通过某种方式得到服务器端的代理对象。
2)客户端通过调用服务器代理对象的方法向服务器端发送请求。
3)代理对象把用户请求通过Android内核(Linux内核)的Binder驱动发送到服务器进程。
4)服务器进程处理用户请求,并通过Android内核(Linux内核)的Binder驱动返回处理结果给客户端的服务器代理对象。
5)客户端收到服务器端的返回结果。
B、binder机制的组成
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接口.
3、AIDL--远程服务
1)在Android中, 每个应用程序都有自己的进程,当需要在不同的进程之间传递对象时,该如何实现呢? 显然, Java中是不支持跨进程内存共享的。
因此要传递对象, 需要把对象解析成操作系统能够理解的数据格式, 以达到跨界对象访问的目的。在JavaEE中,采用RMI通过序列化传递对象。
在Android中, 则采用AIDL(Android InterfaceDefinition Language:接口定义语言)方式实现。
2)什么是AIDL?
AIDL是一种接口定义语言,用于约束两个进程间的通讯规则,供编译器生成代码,实现Android设备上的两个进程间通信(IPC)。
原理:进程之间的通信信息,首先会被转换成AIDL协议消息,然后发送给对方,对方收到AIDL协议消息后再转换成相应的对象。
由于进程之间的通信信息需要双向转换,所以android采用代理类在背后实现了信息的双向转换,代理类由android编译器生成,对开发人员来说是透明的。
3)使用AIDL实现进程间通信的步骤:
a、远程服务应用中:
远程服务端,也就是RemoteService应用中,在src下某个包中创建一个处理业务的接口类
package.cn.itcast.bh.service;
public interface IStudentService{
public String query(int no);
}
然后,根据后面注意事项中的规则,将接口的代码做一些处理,变成如下:
package.cn.itcast.bh.service;
interface IStudentService{
String query(int no);
}
然后,将相应的接口文件的后缀名改为“ .aidl”.
然后,刷新,则系统会在gen目录下生成一个Java文件,会用到这个Java文件中的类及其内部类。
(注意:如果项目中还有有错误的地方,系统则无法根据AIDL生成Java代码。
远程服务的类文件如下:
其中,(1)部分,是来自于系统根据AIDL生成的Java类的一个内部类,远程服务的onBind方法返回的IBinder对象,必须是该类(IstudentService.Stub)的子类的对象。
pcakage cn.itcast.bh.remoteService;
import cn.itcast.bh.service.IStudentService;
public class StudentRemoteService extends Service{
private String[] students = new String[]{"张","郭","李","lihao"};
private MyBinder myBinder = new MyBinder();
@override
public IBinder onBind(Intent intent) {
return myBinder;
}
private final class MyBinder extends IStudentService.Stub(1){
public String query(int no) throws RemoteException{
return students[no];
}
}
}