AIDL介绍
我们通常比较熟悉Android应用程序中进行跨进程访问的组件BroadcastReceiver和ContentProvider,另外一个Android应用程序组件Service也可以,这种可以跨进程访问的服务称为AIDL服务。
AIDL (Android Interface Definition Language)是 Android 提供的一种机制,允许通过跨进程的接口实现不同应用或进程之间的通信。
AIDL 的基本原理
在 Android 中,每个应用运行在自己的独立进程中。当需要跨进程进行通信时,应用间的对象无法直接传递和共享,必须通过 AIDL 接口进行通信。AIDL 会自动生成接口代码来处理复杂的数据类型和方法调用,从而使两个进程可以在不直接共享内存的情况下进行数据交换。
AIDL 使用类似于 Java 接口的语法,并定义一个接口来描述客户端和服务端之间的交互方法。Android 系统通过这一接口来生成代理类和实际实现类,从而实现跨进程调用。
AIDL 的基本工作流程
- 定义 AIDL 接口:在服务端应用中,定义一个 AIDL 文件,描述客户端和服务端之间的通信接口。
- 生成 Java 接口:使用 AIDL 文件,Android 编译器会自动生成对应的 Java 接口代码。该代码会包含一个接口类(Stub 类)和一个客户端代理类(Proxy 类)。
- 实现接口:服务端实现生成的接口方法,客户端通过代理类调用这些方法。
- 绑定服务:客户端通过 bindService() 将服务绑定到自己的进程,从而可以通过 AIDL 接口调用服务端的功能。
AIDL使用
通常一个apk就是一个进程,要实现进程间通信需要两个进程,一个作为服务端,一个作为客户端,服务端来定义AIDL接口,写接口实现,客户端可以调用服务端的AIDL接口实现功能。
注意:实现AIDL需要系统权限,准备工作需要在两个进程中都添加系统权限和系统签名。
这里创建一个Project工程,其中的app包名设置为com.example.aidlserver,作为AIDL的服务端,然后新建一个module作为AIDL的客户端,包名设置为com.example.aidlclient
AIDL服务端
1. 定义AIDL服务接口
先在com.example.aidlserver中创建AIDL接口,选中包名右键新建AIDL,接口名为IAidlServer。


在IAidlServer.aidl中增加add()和minus()两个功能接口。
<app/main/aidl/com.example.aidlserver/IAidlServer.aidl>
interface IAidlServer {
/**
* 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);
int add(int num1, int num2);
int minus(int num1, int num2);
}
定义好AIDL接口后先编译一遍,编译之后Android会自动生成AIDL的服务接口,其中实现了stub、proxy的class,以及TRANSACTION的code,用来通信处理。

2. 实现AIDL服务接口
在com.example.aidlserver中创建Service服务类,实现AIDL中的功能接口。
<app/main/java/com.example.aidlserver/AidlServer.java>
public class AidlServer extends Service {
private static final String TAG = "=== AidlServer ===";
// 服务实体
private final IAidlServer.Stub mStub = new IAidlServer.Stub() {
@Override
public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {
Log.d(TAG, "basicTypes ");
}
@Override
public int add(int num1, int num2) throws RemoteException {
int sum = num1 + num2;
Log.d(TAG, "add sum = " + sum);
return sum;
}
@Override
public int minus(int num1, int num2) throws RemoteException {
int differ = num1 - num2;
Log.d(TAG, "minus differ = " + differ);
return differ;
}
};
@Override
public void onCreate() {
super.onCreate();
Log.d(TAG, "onCreate ");
}
@Override
public IBinder onBind(Intent intent) {
Log.d(TAG, "onStart ");
return mStub;
}
}
3. 静态注册Service
在AndroidManifest.xml中静态注册AIDL的实现类,将Service对外暴露,这样客户端才能访问。
<app/main/AndroidManifest.xml>
<service android:name=".AidlServer"
android:enabled="true"
android:exported="true">
<!-- enable:ture设置可用 exported:ture对外暴露 -->
<intent-filter>
<action android:name="com.example.aidlserver.aidlserver"/>
</intent-filter>
</service>
AIDL客户端
1. 复制服务端的AIDL服务接口
把服务端的AIDL以及包目录完整的拷贝到客户端的mian目录下,让Client和Server的服务对象对等。

AIDL接口复制到客户端之后编辑aidlclient模块,在客户端的build中生成服务接口。

2. 在客户端绑定服务使用接口
首先在客户端的MainActivity页面中添加两个按钮,分别用来触发实现add和minus功能。
然后在MainActivity.java中调用AIDL接口实现功能。
(1)绑定AIDL服务。
(2)调用接口。
(3)解绑AIDL服务。
<aidl/main/java/com.example.aidlserver/MainActivity.java>
public class MainActivity extends AppCompatActivity {
private static final String TAG = "=== AidlClient ===";
private IAidlServer aidlServer;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
protected void onResume() {
super.onResume();
// 绑定 AidlService
Intent intent = new Intent();
intent.setAction("com.example.aidlserver.aidlserver");
intent.setPackage("com.example.aidlserver"); // server's package name
boolean isBound = bindService(intent, connection, BIND_AUTO_CREATE);
Log.d(TAG, "绑定服务 bindService result: " + isBound);
initView();
}
@Override
protected void onDestroy() {
super.onDestroy();
// 解绑 AidlService
unbindService(connection);
Log.d(TAG, "解绑服务 unbindService finished !");
}
private void initView(){
// add
findViewById(R.id.add).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Log.d(TAG, "add onClick : " + (aidlServer == null));
if (aidlServer != null) {
try {
int sum = aidlServer.add(12, 34);
Log.d(TAG, "sum = " + sum);
Toast.makeText(MainActivity.this, String.valueOf(sum), Toast.LENGTH_SHORT).show();
} catch (RemoteException e) {
e.printStackTrace();
Log.e(TAG, "AidlServer.add error : " + e);
}
}
}
});
// minus
findViewById(R.id.minus).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Log.d(TAG, "differ onClick : " + (aidlServer == null));
if (aidlServer != null) {
try {
int differ = aidlServer.minus(34, 12);
Log.d(TAG, "differ = " + differ);
Toast.makeText(MainActivity.this, String.valueOf(differ), Toast.LENGTH_SHORT).show();
} catch (RemoteException e) {
e.printStackTrace();
Log.e(TAG, "aidlService.minus error : " + e);
}
}
}
});
}
private final ServiceConnection connection = new ServiceConnection() {
// 绑定服务成功
@Override
public void onServiceConnected(ComponentName componentName, IBinder service) {
// 接受到了远程的服务
Log.d(TAG, "onServiceConnected!");
aidlServer = IAidlServer.Stub.asInterface(service);
}
// 解绑服务
@Override
public void onServiceDisconnected(ComponentName componentName) {
Log.d(TAG, "onServiceDisconnected!");
// 回收资源
aidlServer = null;
}
};
}
先运行服务端,再运行客户端,点击客户端的按钮就可以实现AIDL的接口功能了。