最近做了个服务端和客户端两个APK进行AIDL通行的项目,总结一下在实现个过程中应该注意的问题。
1、因为服务端和客户端的AIDL相关的文件必须在名称相同的包中,为了避免来回的拷贝文件出现错误,最好把AIDL相关的单独生成一个JAR包,供服务端和客户端使用。
2、自定义的参数类需要实现Parcelable接口,并实现接口中的相关方法,栗:
public class HSFEVerifyResult implements Parcelable{
public boolean pass;
public float score;
public int faceId;
public int frameId;
public int channelId;
public byte[] image;
public int verifyTime;
public String rect;
public HSFEVerifyResult() {
}
public HSFEVerifyResult(Parcel source) {
this.pass = source.readByte() == 1 ? true : false;
this.score = source.readFloat();
this.faceId = source.readInt();
this.frameId = source.readInt();
this.channelId = source.readInt();
this.image = source.createByteArray();
this.verifyTime = source.readInt();
this.rect = source.readString();
}
@Override
public String toString() {
return "HSFEVerifyResult [pass=" + pass + ", score=" + score + ", faceId=" + faceId + ", frameId=" + frameId
+ ", channelId=" + channelId + ", image=" + image + ", verifyTime=" + verifyTime + "]";
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeByte((byte) (pass ? 1 : 0)); //if myBoolean == true, byte == 1
dest.writeFloat(score);
dest.writeInt(faceId);
dest.writeInt(frameId);
dest.writeInt(channelId);
if(image != null){
dest.writeByteArray(image);
}
dest.writeInt(verifyTime);
dest.writeString(rect);
}
public static final Parcelable.Creator<HSFEVerifyResult> CREATOR = new Creator<HSFEVerifyResult>() {
@Override
public HSFEVerifyResult[] newArray(int size) {
return new HSFEVerifyResult[size];
}
@Override
public HSFEVerifyResult createFromParcel(Parcel source) {
return new HSFEVerifyResult(source);
}
};
public void readFromParcel(Parcel source) {
this.pass = source.readByte() == 1 ? true : false;
this.score = source.readFloat();
this.faceId = source.readInt();
this.frameId = source.readInt();
this.channelId = source.readInt();
if(source.createByteArray() != null){
this.image = source.createByteArray();
}
this.verifyTime = source.readInt();
this.rect = source.readString();
}
生成好参数文件后还要声明参数,是以一个.aidl文件的形式 栗:HSFEVerifyresult.aidl
package com.hisign.engine.aidl;
parcelable HSFEVerifyResult;
3、注意btye[]数组和boolean类型的读写 4、在使用参数文件时要注意引入包,即使在同一个包下也要引用,并指明参数的传输方向
package com.hisign.engine.aidl;
import com.hisign.engine.aidl.THIDFaceRect;
import com.hisign.engine.aidl.HSFEVerifyResult;
interface IExecuteCmdProxy {
void onDetectResult(String results,int faceNum);
//void onDetectResult(out THIDFaceRect[] rect,int faceNum);
void onVerifyResult(inout HSFEVerifyResult verifyResult);
}
5、错误排查
,有时远程方法调用出现问题时,错误会报在.aidl自动生成的JAVA文件中,但是这个文件是自动生成的,我们又改不了……,这时需要每一个远程接口服务的实现中重写onTransact
private IExecuteCmdProxy mCmdProxy = new IExecuteCmdProxy.Stub() {
@Override
public void onDetectResult(String rects, int faceNum) throws RemoteException {
}
public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws RemoteException {
try {
super.onTransact(code, data, reply, flags);
} catch (RuntimeException e) {
Log.d("lixm", "Unexpected remote exception", e);
throw e;
}
return true;
}
@Override
public void onVerifyResult(final HSFEVerifyResult hsfeVerifyResult) throws RemoteException {
}
};
**
6、客户端向服务端注册回调为 空 的问题
**
private OnResultProxy onResultProxy = new OnResultProxy.Stub() {
@Override
public void onSetBeiDouResult(boolean isOk, String msg) throws RemoteException {
Log.d("lixm",isOk+" TestMainActivity 收到 g "+msg);
}
@Override
public void onServerCommond() throws RemoteException {
}
@Override
public IBinder asBinder() {
return null;
}
};
主要原因是这个方法:
@Override
public IBinder asBinder() {
return null;
}
把这个方法注释掉就可以了