目录
AIDL
AIDL(Android Interface Define Language)是一种IPC通信方式,我们可以利用它来定义两个进程相互通信的接口。它的本质是C/S架构的,需要一个服务端,一个客户端。
服务端的使用方法
首先添加一个module作为服务端,在main目录下创建aidl目录。
开始创建aidl文件 IMyAidlInterface.aidl,在aidl文件中添加接口方法。
interface IMyAidlInterface {
/**
* 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);
String getWord();
void setWord(String word);
}
编译程序,在android模式下java(generated) 文件里就能看到自动生成的JAVA文件:IMyAidlInterface.java文件
编写Service类,在MyService内部声明一个IBinder对象,它是一个匿名实现的IMyAidlInterface.Stub的实例,同时在IMyAidlInterface.Stub实例中实现在aidl中声明的供客户端调用的方法。
public class MyService extends Service {
private static final String TAG = "MyService";
private String myWord;
private IMyAidlInterface.Stub mBinder = new IMyAidlInterface.Stub() {
@Override
public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {
}
@Override
public String getWord() throws RemoteException {
return myWord;
}
@Override
public void setWord(String word) throws RemoteException {
myWord = word;
Log.d(TAG, "setWord:" + word);
}
};
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
客户端的使用方法
在客户端跟服务器一样,新建aidl目录,将服务器端的aidl拷贝到客户端,注意的是拷贝后的客户端的aidl文件包目录必须与服务器端保持一致,拷贝完后同样时编译工程,让客户端也生成对应的java文件
实现ServiceConnection接口,调用bindService绑定服务,传入生成的ServiceConnection实例;在onServiceConnected()实现中,将收到的IBinder实例(名为 service)。调用 XXX.Stub.asInterface((IBinder)service),以将返回的参数转换为 AIDL生成的接口类型。
private ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
//返回的IBinder类型参数转换为 AIDL生成的接口类型
mService = IMyAidlInterface.Stub.asInterface(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
//断开服务
mService = null;
}
};
private void bindService() {
Intent intent = new Intent();
intent.setComponent(new ComponentName("com.example.aidlserver", "com.example.aidlserver.MyService"));
bindService(intent, connection, Context.BIND_AUTO_CREATE);
}
通过调用生成的AIDL接口实例中对应的方法就可以实现IPC调用了;
在不使用的时候解除服务的绑定Context.unbindService()。
@Override
protected void onDestroy() {
super.onDestroy();
unbindService(mService);
}
概括AIDL的用法,就是服务端里有一个Service,为客户端进程提供Binder对象。客户端通过AIDL接口的静态方法asInterface 将Binder对象转化成AIDL接口的代理对象,通过这个代理对象就可以发起远程调用请求了。
参考文档: