Android AIDL之in out inout

Android AIDL之in out inout

可能很多人会不清楚定义aidl接口到底如何定义为好,这里还是总结一下,毕竟笔记是最深刻的理解。

一、aidl支持哪些数据类型呢?
  • Java 编程语言中的所有原语类型(如 int、long、char、boolean、String、CharSequence 等等)
  • List
    List中的所有元素都必须是以上列表中支持的数据类型、其他 AIDL 生成的接口或您声明的可打包类型。 可选择将 List 用作“通用”类(例如,List)。另一端实际接收的具体类始终是 ArrayList,但生成的方法使用的是 List 接口。
  • Map
    Map中的所有元素都必须是以上列表中支持的数据类型、其他 AIDL 生成的接口或您声明的可打包类型。 不支持通用 Map(如 Map
二、定义服务接口时,请注意:
  • 方法可带零个或多个参数,返回值或空值。
  • 所有非原语参数都需要指示数据走向的方向标记。可以是 in、out 或 inout
    原语默认为 in,不能是其他方向。
  • .aidl 文件中包括的所有代码注释都包含在生成的 IBinder 接口中(import 和 package 语句之前的注释除外)
  • .aidl 文件中方法名不能重复,不管参数是否相同
  • 只支持方法;不能公开 AIDL 中的静态字段。
三、in out inout
1. 原语类型
//定义接口
void getXutaoTestData(int value); //测试1
void getXutaoTestData(in int value); //测试2
void getXutaoTestData(out int value); //测试3
void getXutaoTestData(inout int value); //测试4
//客户端
int value = 5;
PlaybackServiceUtil.getXutaoTestData(value);
sService.getXutaoTestData(value);
KGLog.d("xutaoxutao123", "Util: value = " + value);
//服务端(service)
@Override
public void getXutaoTestData(int value) throws RemoteException {
    try {
        KGLog.d("xutaoxutao123", "Service: value = " + value);
        value = -1;
    }catch (Exception e){
        AidlExceptionMgr.processAidlExp(e);
    }
}

//测试1,测试2 结果相同
com.kugou.android.support D/xutaoxutao123: Service: value = 5
com.kugou.android D/xutaoxutao123: Util: value = 5
//测试3,测试4 编译不过

//结论:原语默认为in,且不能是out或inout
2. 非原语类型,例float[]

只贴出部分代码

//定义接口
void getXutaoTestData(float[] value); //测试1
void getXutaoTestData(in float[] value); //测试2
void getXutaoTestData(out float[] value); //测试3
void getXutaoTestData(inout float[] value); //测试4
//客户端
float[] value = new float[]{1f, 2f, 3f};
PlaybackServiceUtil.getXutaoTestData(value);
sService.getXutaoTestData(value);
KGLog.d("xutaoxutao123", "Util: value[0] = " + value[0] 
+ ", value[1] = " + value[1] + ", value[2] = " + value[2]);
//服务端(service)
@Override
public void getXutaoTestData(float[] value) throws RemoteException {
    try {
        KGLog.d("xutaoxutao123", "Service: value[0] = " + value[0] 
        + ", value[1] = " + value[1] + ", value[2] = " + value[2]);
        value[0] = 0.1f;
        value[1] = 0.2f;
        value[2] = 0.3f;
    }catch (Exception e){
        AidlExceptionMgr.processAidlExp(e);
    }
}

//测试1,编译不过
//测试2,服务端可以接收到客户端数据,客户端不能接收到服务端数据
Service: value[0] = 1.0, value[1] = 2.0, value[2] = 3.0
Util: value[0] = 1.0, value[1] = 2.0, value[2] = 3.0
//测试3,服务端不能接收到客户端数据,客户端能接收到服务端数据
Service: value[0] = 0.0, value[1] = 0.0, value[2] = 0.0
Util: value[0] = 0.1, value[1] = 0.2, value[2] = 0.3
//测试4,服务端能接收到客户端数据,客户端也能接收到服务端数据
Service: value[0] = 1.0, value[1] = 2.0, value[2] = 3.0
Util: value[0] = 0.1, value[1] = 0.2, value[2] = 0.3

//如果服务端value = new float[]{0.1f, 0.2f, 0.3f},则不能接收到服务端数据;
Service: value[0] = 0.0, value[1] = 0.0, value[2] = 0.0
Util: value[0] = 0.0, value[1] = 0.0, value[2] = 0.0

//结论:非原语要带上in、out或inout,否则编译不过;in,out与inout使用方法如上。
3. in out inout是怎么做到数据方向的控制呢?

Android SDK 工具会生成一个以 .aidl 文件命名的 .java 接口文件。生成的接口包括一个名为 Stub 的子类,这个子类是其父接口(例如,IKugouPlaybackService.Stub)的抽象实现,用于声明 .aidl 文件中的所有方法。

// .java接口文件中数据传输
@Override public void getXutaoTestData(float[] value) throws android.os.RemoteException
{
    android.os.Parcel _data = android.os.Parcel.obtain();
    android.os.Parcel _reply = android.os.Parcel.obtain();
    try {
        _data.writeInterfaceToken(DESCRIPTOR);
        _data.writeFloatArray(value); //有in时将value写给_data
        /* 没有in的时候是这样的
        if ((value==null)) {
            _data.writeInt(-1);
        }else {
            _data.writeInt(value.length);
        }
        */
        mRemote.transact(Stub.TRANSACTION_getXutaoTestData, _data, _reply, 0);
        _reply.readException();
        _reply.readFloatArray(value); //有out时将_reply读回给value
        //没有out的时候是这样的,就没有_reply.readFloatArray(value)这句代码
    }
    finally {
        _reply.recycle();
        _data.recycle();
    }
}

//没有in只有out的时候只传了一个空数组过去,所以服务端接收不到数据,但客户端可以接收数据
case TRANSACTION_getXutaoTestData:
{
    data.enforceInterface(DESCRIPTOR);
    float[] _arg0;
    int _arg0_length = data.readInt();
    if ((_arg0_length<0)) {
        _arg0 = null;
    }
    else {
        _arg0 = new float[_arg0_length]; 
    }
    this.getXutaoTestData(_arg0);
    reply.writeNoException();
    reply.writeFloatArray(_arg0);
    return true;
}
//

就这些了,有什么不对请指出!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值