什么是aidl?
AIDL:Android Interface Definition Language,即Android接口定义语言。
aidl有什么用?
Android系统中的进程之间不能共享内存,因此,需要提供一些机制在不同进程之间进行数据通信。
为了使其他的应用程序也可以访问本应用程序提供的服务,Android系统采用了远程过程调用(Remote Procedure Call,RPC)方式来实现。与很多其他的基于RPC的解决方案一样,Android使用一种接口定义语言(Interface Definition Language,IDL)来公开服务的接口。我们知道4个Android应用程序组件中的3个(Activity、BroadcastReceiver和ContentProvider)都可以进行跨进程访问,另外一个Android应用程序组件Service同样可以。因此,可以将这种可以跨进程访问的服务称为AIDL(Android Interface Definition Language)服务。
demo所用到的:
1.server端。
说白了就是一个应用,作为被调用方,挂起一个serivce,在service的onBind回调中返回一个IBinder对象,IBinder对象来自于aidl编译后产生的对应IMyAidlInterface.java的对象的Stub方法,然后再实现aidl定义的接口即可。
//文件路径:./MyApplication2/app/src/main/java/com/example/myapplication2/MyService.java
public class MyService extends Service {
@Nullable
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
private Binder mBinder = new IMyAidlInterface.Stub() {
@Override
public int sum(int a, int b) throws RemoteException {
return a + b - 1;
}
};
}
-----------
//文件路径:./MyApplication2/app/src/main/aidl/com/example/myapplication2/IMyAidlInterface.aidl
//注意!!!IMyAidlInterface.aidl的路径是在aidl目录底下
package com.example.myapplication2;
interface IMyAidlInterface {
int sum(int a, int b);
}
当然,这里还需要把service挂起。就是在activity中startService,这里不展示代码了。
可以通过adb shell dumpsys activity services com.example.myapplication2
贴一下AndroidManifest.xml中MyService的声明
<!--需要设置exported为true,将service暴露出去-->
<service android:name=".MyService"
android:exported="true" />
2.client端。
客户端同样是一个应用,作为调用方。所需要做的就是把客户端的aidl文件copy一份到自己的项目中。
然后bindService,在服务已连接的回调中拿到IBinder对象作为IMyAidlInterface.Stub.asInterface的入参,可获得IMyAidlInterface对象,调用接口定义的方法sum(int a, int b)即完全aidl流程。
int result = aidlInterface.sum(1, 1);
返回result为1,验证成功。
package com.example.myapplication;
//...
import com.example.myapplication2.IMyAidlInterface;
//注意!!!这里客户端的包名是com.example.myapplication,
//import的IMyAidlInterface包名是com.example.myapplication2。
@Override
protected void onStart() {
super.onStart();
Intent intent = new Intent();
intent.setPackage("com.example.myapplication2");
intent.setComponent(new ComponentName("com.example.myapplication2",
"com.example.myapplication2.MyService"));
bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);
}
@Override
protected void onDestroy() {
super.onDestroy();
unbindService(mServiceConnection);
}
private ServiceConnection mServiceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
IMyAidlInterface aidlInterface = IMyAidlInterface.Stub.asInterface(service);
try {
int result = aidlInterface.sum(1, 1);
Log.e("qinbin", "aidl success,result = " + result);
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
Log.e("qinbin", "onServiceDisconnected");
}
};