转载请注明来自:http://blog.csdn.net/ly20116/article/details/51112833
AIDL(Android Interface Definition Language),它允许你定义客户端与服务端达成一致的程序接口使用进程间通信( interprocess communication ,IPC)相互交流。
在Android上面,一个进程不能正常的访问另一个进程的内存。 所以说,他们需要分解他们的对象为操作系统可以理解的基本单位,然后为你把这些对象按次序跨越进程边界 书写这些代码是单调冗长的,所以android使用AIDL为你处理这个问题。
AIDL IPC机制是面向接口的,它是使用代理类在客户端和实现端传递数据
注意:使用AIDL只有在你允许来自不同应用的客户端跨进程通信访问你的service,并且想要在你的service种处理多线程的时候才是必要的。
你必须在一个.aidl文件中使用java编程语言语法定义你的AIDL接口,然后在提供service的应用中和任何绑定到这个service的应用中的源代码中(在src目录下)保存它
当你编译包含.aidl文件的应用时,Android SDK工具基于这个.aidl文件生成一个IBinder接口,并且把它保存到项目的gen目录吓 service必须恰当的实现这个IBinder接口 之后客户端应用可以绑定到这个服务上,然后从IBinder调用方法来执行IPC
1、创建AIDL文件
IServiceAidlInterface.aidl:
// IServiceAidlInterface.aidl
package com.yang.serviceaidl;
// Declare any non-default types here with import statements
interface IServiceAidlInterface {
/**
* Demonstrates some basic types that you can use as parameters
* and return values in AIDL.
*/
void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,double aDouble, String aString);
void setData(String data);//自定义方法声明
}
默认的,AIDL支持下面数据类型:
List
List中的所有元素必须是AIDL支持的类型之一,或者是一个其他AIDL生成的接口,或者是你定义的parcelable
List可以使用范型(例如,List) 接收端的实际类经常是一个ArrayList,尽管方法是使用List接口生成的
Map
Map中的所有元素必须是AIDL支持的类型之一,或者是一个其他AIDL生成的接口,或者是你定义的parcelable范型map是不被支持的(比如这种形式Map) 接收端的实际类经常是一个HashMap,尽管方法是使用Map接口生成的
对于上述类型之外的类型,你必须声明 import ,即使在同一个包内
简单的保存你的.aidl文件在你工程的src目录下,当你build你的应用时,SDK工具在你工程的gen目录下生成IBinder接口文件 生成的文件名字与.aidl名字匹配,但是是以.java为扩展名(例如IRemoteService.aidl对应为IRemoteService.java)
2、实现接口
在你定义的Service中onBind方法
@Override
public IBinder onBind(Intent intent) {
return new IServiceAidlInterface.Stub() {
@Override
public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {
}
@Override
public void setData(String data) throws RemoteException {
AppService.this.data=data;
}
};
}
Stub类(如IServiceAidlInterface.Stub())是它父类的抽象实现,并且声明了.aidl中所有的方法,
Stub的asInterface()方法,它是用来接收一个IBinder(通常IBinder传递给客户端的onServiceConnected()回调方法)并且返回一个Stub接口的实例。
注意事项:
抛出的异常不会返回给调用者
3、客户端获取接口
如果是跨应用调用Service,那么你应该在另一个应用中一模一样的AIDL文件(包名,类名相同等等),。如下图结构:
在androidapp工程中建立一个与app工程相同的AIDL文件,包括包名。
跨应用启动Service的Intent(显示调用方法);
Intent serviceIntent=new Intent();
serviceIntent.setComponent(new ComponentName("com.yang.serviceaidl","com.yang.serviceaidl.AppService"));
参数说明:
1. 包名
2. 类名
//启动服务 startService(serviceIntent);
//关闭服务 stopService(serviceIntent);
//绑定服务 bindService(serviceIntent,this,Context.BIND_AUTO_CREATE);
//解绑服务 unbindService(this);
在androidapp中调用给接口,在MainActivity(实现了ServiceConnection接口)中onServiceConnected()方法中
private IServiceAidlInterface binder=null;
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
// binder= (IServiceAidlInterface) service; //错误的
binder=IServiceAidlInterface.Stub.asInterface(service);
}
类似于Service的绑定通信。
传递数据:
if(binder!=null){
try {
binder.setData(data.getText().toString());
} catch (RemoteException e) {
e.printStackTrace();
}
}
总结:调用IPC方法步骤:
果你想通过IPC接口把一个类从一个进程传递到另一个进程中,那么是可以的。 然而,你必须保证为你的类而写的代码也是对IPC通道另一端是可用的,并且你的类必须支持Parcelable接口 支持Parcelable接口是很重要的,因为它允许Android系统把对象分解为可以被组织跨进程传输基本单元
为了建立一个支持Parcelable协议的类,你必须遵守下面的规则:
AIDL使用代码中的这些域和方法封装传送和解读你的对象
Rect.aidl文件:
package android.graphics;
// Declare Rect so AIDL can find it and knows that it implements
// the parcelable protocol.
parcelable Rect;
Rect类:
public final class Rect implements Parcelable {
public int left;
public int top;
public int right;
public int bottom;
public static final Parcelable.Creator CREATOR = new
Parcelable.Creator() {
public Rect createFromParcel(Parcel in) {
return new Rect(in);
}
public Rect[] newArray(int size) {
return new Rect[size];
}
};
public Rect() {
}
private Rect(Parcel in) {
readFromParcel(in);
}
public void writeToParcel(Parcel out) {
out.writeInt(left);
out.writeInt(top);
out.writeInt(right);
out.writeInt(bottom);
}
public void readFromParcel(Parcel in) {
left = in.readInt();
top = in.readInt();
right = in.readInt();
bottom = in.readInt();
}
}
AIDL是android接口定义语言,主要是android中用来解决进程间通信(interprocess communication ,IPC)的。
它和绑定服务通信实现类似,不过是绑定服务通信时我们继承Binder实现的接口MyBinder变成了AIDL实现。
AIDL实例下载链接