1.aidl使用
1.aidl文件
// ICalculator.aidl
package com.huntergao.demoserver;
// Declare any non-default types here with import statements
interface ICalculator {
int plus(int aInt, int bInt);
int minus(int aInt, int bInt);
}
aidl文件添加完毕之后会自动生成ICalculator类, 存放位置
build/generated/source/aidl/debug/com.huntergao.demoserver.ICalculator.java
2.服务端
public class CalculateService extends Service {
private static final String TAG = "CalculateService";
private final Binder binder = new ICalculator.Stub() {
@Override
public int plus(int aInt, int bInt) throws RemoteException {
return aInt + bInt;
}
@Override
public int minus(int aInt, int bInt) throws RemoteException {
return aInt - bInt;
}
};
@Override
public void onCreate() {
super.onCreate();
Log.i(TAG, "onCreate");
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
Log.i(TAG, "onBind, intent = " + intent);
return binder;
}
}
服务端主要是实现ICalculator.Stub接口,创建Binder类
在AndroidManifest.xml注册服务
<service
android:name="com.huntergao.demoserver.CalculateService"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.DEMO_CALCULATE_ACTION" />
</intent-filter>
</service>
3.客户端
客户端也要放入ICalaulator.aidl文件,且包名和服务端的一致,否则会报错误:
java.lang.SecurityException: Binder invocation to an incorrect interface
创建ServiceConnection
private ServiceConnection serviceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
Log.i(TAG, "onServiceConnected");
calculator = ICalculator.Stub.asInterface(iBinder);
try {
int sum = calculator.plus(5, 3);
Log.d(TAG, sum + "");
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
Log.i(TAG, "onServiceDisconnected, componentName =" + componentName);
}
};
绑定服务
Intent intent = new Intent();
intent.setAction("android.intent.action.DEMO_CALCULATE_ACTION");
// 隐式启动必须设置包名
intent.setPackage("com.huntergao.demoserver");
bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
在这里启动,不要使用
intent.setClassName("com.huntergao.multiscreen", "com.huntergao.demoserver.CalculateService");
解绑服务
unbindService(serviceConnection);
2.分析AIDL生成的代码
服务端实现了ICalculator.Stub类
public static abstract class Stub extends android.os.Binder implements com.huntergao.demoserver.ICalculator {
// 每一个Binder服务都有一个唯一的标识
private static final java.lang.String DESCRIPTOR = "com.huntergao.demoserver.ICalculator";
/**
* Construct the stub at attach it to the interface.
*/
public Stub() {
this.attachInterface(this, DESCRIPTOR);
}
/**
* Cast an IBinder object into an com.huntergao.demoserver.ICalculator interface,
* generating a proxy if needed.
* 该方法由客户端调用,判断binder对象是否处于本进程,处于本进程返回ICalculator对象,否则返回Stub.Proxy对象
*/
public static com.huntergao.demoserver.ICalculator asInterface(android.os.IBinder obj) {
if ((obj == null)) {
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin != null) && (iin instanceof com.huntergao.demoserver.ICalculator))) {
return ((com.huntergao.demoserver.ICalculator) iin);
}
return new com.huntergao.demoserver.ICalculator.Stub.Proxy(obj);
}
@Override
public android.os.IBinder asBinder() {
return this;
}
// 当服务端接收到客户端依靠Binder驱动发来的消息时,执行onTransact方法,然后由参数决定执行服务端的代码
// code 唯一标识,用于区分执行哪个参数,客户端会传递该参数
// data 客户端传递过来的参数
// reply 服务端返回的值
// flag标明是否有返回值,0为有(双向),1为没有(单向)
@Override
public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException {
switch (code) {
case INTERFACE_TRANSACTION: {
reply.writeString(DESCRIPTOR);
return true;
}
case TRANSACTION_plus: {
data.enforceInterface(DESCRIPTOR);
int _arg0;
_arg0 = data.readInt();
int _arg1;
_arg1 = data.readInt();
int _result = this.plus(_arg0, _arg1);
reply.writeNoException();
reply.writeInt(_result);
return true;
}
case TRANSACTION_minus: {
data.enforceInterface(DESCRIPTOR);
int _arg0;
_arg0 = data.readInt();
int _arg1;
_arg1 = data.readInt();
int _result = this.minus(_arg0, _arg1);
reply.writeNoException();
reply.writeInt(_result);
return true;
}
}
return super.onTransact(code, data, reply, flags);
}
private static class Proxy implements com.huntergao.demoserver.ICalculator {
private android.os.IBinder mRemote;
Proxy(android.os.IBinder remote) {
mRemote = remote;
}
@Override
public android.os.IBinder asBinder() {
return mRemote;
}
public java.lang.String getInterfaceDescriptor() {
return DESCRIPTOR;
}
@Override
public int plus(int aInt, int bInt) throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
int _result;
try {
// 将参数写入data对象,传给服务端
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeInt(aInt);
_data.writeInt(bInt);
// 调用transact执行服务端代码
mRemote.transact(Stub.TRANSACTION_plus, _data, _reply, 0);
_reply.readException();
// 获取服务端的结果
_result = _reply.readInt();
} finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
@Override
public int minus(int aInt, int bInt) throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
int _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeInt(aInt);
_data.writeInt(bInt);
mRemote.transact(Stub.TRANSACTION_minus, _data, _reply, 0);
_reply.readException();
_result = _reply.readInt();
} finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
}
static final int TRANSACTION_plus = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
static final int TRANSACTION_minus = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
}