一、AIDL架构基础
1. 核心设计原理
AIDL基于客户端-服务器架构,通过Binder机制实现跨进程方法调用。其核心设计采用Proxy-Stub模式:
- Proxy:客户端代理,负责序列化请求参数并发送给Binder驱动
- Stub:服务端骨架,负责反序列化参数并调用实际方法实现
2. Binder驱动层
作为Linux内核模块,Binder驱动负责:
- 进程间数据传递
- 线程调度管理
- 引用计数维护
- 安全权限验证
二、AIDL编译生成机制
1. 接口定义示例
java
// IRemoteService.aidl
package com.example;
interface IRemoteService {
int calculate(in int param1, in int param2);
void registerListener(IRemoteListener listener);
void unregisterListener(IRemoteListener listener);
}
2. 生成的Java代码结构
Stub抽象类(服务端基础)
java
public static abstract class Stub extends Binder implements IRemoteService {
private static final String DESCRIPTOR = "com.example.IRemoteService";
// 方法标识常量
static final int TRANSACTION_calculate = (IBinder.FIRST_CALL_TRANSACTION + 0);
static final int TRANSACTION_registerListener = (IBinder.FIRST_CALL_TRANSACTION + 1);
static final int TRANSACTION_unregisterListener = (IBinder.FIRST_CALL_TRANSACTION + 2);
public Stub() {
attachInterface(this, DESCRIPTOR);
}
public static IRemoteService asInterface(IBinder obj) {
if (obj == null) return null;
// 查询本地接口(同进程直接返回)
IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (iin != null && iin instanceof IRemoteService) {
return (IRemoteService) iin;
}
// 跨进程返回代理
return new Proxy(obj);
}
@Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags) {
switch (code) {
case INTERFACE_TRANSACTION:
reply.writeString(DESCRIPTOR);
return true;
case TRANSACTION_calculate:
data.enforceInterface(DESCRIPTOR);
int _arg0 = data.readInt();
int _arg1 = data.readInt();
int _result = this.calculate(_arg0, _arg1);
reply.writeNoException();
reply.writeInt(_result);
return true;
case TRANSACTION_registerListener:
data.enforceInterface(DESCRIPTOR);
IRemoteListener _arg0 = IRemoteListener.Stub.asInterface(data.readStrongBinder());
this.registerListener(_arg0);
reply.writeNoException();
return true;
default:
return super.onTransact(code, data, reply, flags);
}
}
}
Proxy代理类(客户端实现)
java
private static class Proxy implements IRemoteService {
private IBinder mRemote;
Proxy(IBinder remote) {
mRemote = remote;
}
@Override
public IBinder asBinder() {
return mRemote;
}
@Override
public int calculate(int param1, int param2) {
Parcel _data = Parcel.obtain();
Parcel _reply = Parcel.obtain();
int _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeInt(param1);
_data.writeInt(param2);
// 同步跨进程调用
boolean _status = mRemote.transact(TRANSACTION_calculate, _data, _reply, 0);
if (!_status) {
throw new RemoteException("Method calculate failed");
}
_reply.readException();
_result = _reply.readInt();
} finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
}
三、Binder传输机制详解
1. 数据序列化过程
Parcel序列化机制:
java
// 写入过程
_data.writeInterfaceToken(DESCRIPTOR); // 接口标识
_data.writeInt(param1); // 基本类型
_data.writeStrongBinder(callback); // Binder对象
// 读取过程
data.enforceInterface(DESCRIPTOR); // 验证接口
int param1 = data.readInt(); // 读取参数
IBinder binder = data.readStrongBinder(); // 读取Binder
2. 事务传输流程
java
// transact方法参数说明
mRemote.transact(
code, // 方法标识:TRANSACTION_xxx
data, // 输入数据Parcel
reply, // 输出结果Parcel
flags // 传输标志:0-同步,FLAG_ONEWAY-异步
);
3. 线程模型管理
- Binder线程池:默认16个工作线程处理IPC请求
- 同步调用:客户端线程阻塞等待服务端返回
- 异步调用:使用FLAG_ONEWAY标志,不等待返回
四、服务端实现架构
1. Service实现
java
public class RemoteService extends Service {
private final IRemoteService.Stub mBinder = new IRemoteService.Stub() {
@Override
public int calculate(int param1, int param2) {
// 实际业务逻辑
return param1 + param2;
}
@Override
public void registerListener(IRemoteListener listener) {
// 回调注册管理
mListeners.register(listener);
}
@Override
public void unregisterListener(IRemoteListener listener) {
// 回调注销管理
mListeners.unregister(listener);
}
};
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
}
2. 回调接口管理
java
// 死亡监听机制
listener.asBinder().linkToDeath(new DeathRecipient() {
@Override
public void binderDied() {
// 客户端进程死亡处理
mListeners.unregister(listener);
}
}, 0);
五、客户端绑定流程
1. ServiceConnection实现
java
private IRemoteService mService;
private ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
// 将Binder转换为接口
mService = IRemoteService.Stub.asInterface(service);
// 设置死亡监听
service.linkToDeath(mDeathRecipient, 0);
}
@Override
public void onServiceDisconnected(ComponentName name) {
mService = null;
}
};
// 绑定服务
Intent intent = new Intent(this, RemoteService.class);
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
六、性能与安全机制
1. 数据传输优化
- Parcel对象池:避免频繁创建Parcel对象
- 批量操作:减少IPC调用次数
- 数据压缩:对大数据使用合适的序列化方式
2. 安全验证机制
java
@Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags) {
// 权限验证
if (checkCallingOrSelfPermission("com.example.PERMISSION") != PERMISSION_GRANTED) {
throw new SecurityException("Permission denied");
}
// 接口令牌验证
data.enforceInterface(DESCRIPTOR);
return super.onTransact(code, data, reply, flags);
}
3. 引用计数管理
Binder驱动维护对象引用计数,确保:
- 对象在仍有引用时不被销毁
- 跨进程引用正确释放
- 防止内存泄漏
七、高级特性实现
1. 单向调用(oneway)
java
// AIDL定义
oneway void asyncMethod(in int param);
// 生成的Proxy实现
@Override
public void asyncMethod(int param) {
Parcel _data = Parcel.obtain();
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeInt(param);
// FLAG_ONEWAY表示异步调用
mRemote.transact(TRANSACTION_asyncMethod, _data, null, IBinder.FLAG_ONEWAY);
} finally {
_data.recycle();
}
}
2. in/out/inout参数方向
- in:客户端到服务端的输入参数
- out:服务端到客户端的输出参数
- inout:双向参数传递
AIDL通过这套完整的机制,在Android系统中实现了高效、安全的跨进程通信,为系统服务和应用程序之间的交互提供了可靠的基础设施。