天天看点

Android基础|AIDL 中的方向标签 inout 一句话总结

AIDL 定义的接口文件,使用

in

out

inout

方向标签表明数据流向:

  • 原始类型、String、IBinder 参数以及 AIDL 生成的接口参数 只能 用 in 修饰,可以不显式地写出来。
  • 其他类型参数,主要是 Parcel 类型和 List、Map 类型,支持 out、inout,必须显式写出来。

大家只要自己试一下这些参数,并 Build 生成下 Java 文件,就可以发现它们的区别:

  • in:Proxy 端流向 Stub 端,Proxy 端将数据写入 Parcel,通过 BinderDriver 后,Stub 端从 Parcel 中读取。
  • out:Stub 端流向 Proxy 端,Proxy 端不传递此参数,Stub 端创建实例,执行方法后,将更新后的参数写入 Parcel,Proxy 端从 Parcel 中先读取 Reply,再读取更新后的参数。大家可以类比

    List#toArray(T[])

    来理解。
  • inout:Proxy 端写入,Stub 端读取后,执行方法,将更新后的参数传回,Proxy 再读取更新后的参数。大家可以类比

    Arrays#sort(T[])

    来理解。

假设 inout 方向,Proxy 传递

List<String>

[a,b,c],Stub 执行后更新得到 [d,e,f,g],那么最终 Proxy 端读取并更新后 List 的结果就是 [d,e,f,g]。这个过程是通过 Parcle#readStringList 实现的:

public final void readStringList(@NonNull List<String> list) {
    int M = list.size(); // 初始 [a,b,c] List
    int N = readInt();
    int i = 0;
    for (; i < M && i < N; i++) {
        list.set(i, readString()); // 读取 Parcel 中 Stub 返回的 String 元素: d,e,f,g
    }
    for (; i<N; i++) {
        list.add(readString());
    }
    for (; i<M; i++) {
        list.remove(N);
    }
}
           

参考

  1. 「Android Binder」AIDL中的 in / out 到底是啥?