0%

AndroidAIDL

编译器做了什么

通过查看编译后产生的Java文件,观察其结构

构造后的AIDL类产生了一个同名接口,这个接口包含了AIDL内声明的所有方法,并且继承了android.os.IInterface。接口包含了两个静态类:

  • class Default
  • class Stub

Default类默认实现了AIDL接口以及IInterface的asBinder()方法,但都为空实现。

Stub类为具体的AIDL实现类,继承了android.os.Binder类,并实现AIDL接口,接下来看下这个类的结构以及这个类都做了些什么工作。

  • 构造函数。构造函数将AIDL接口与Binder通过一个描述符关联起来,在Binder中,这个attachInterface()是这么描述自身功能的:

    将特定的接口与Binder绑定(其实就是内部变量持有了这个AIDL接口),当调用这个函数之后,使用queryLocalInterface()函数将会返回与Binder绑定的IInterface,即为编译器实现好的AIDL接口的实现类。

  • 一个静态方法,将Binder转换为IInterface,即我们的AIDL接口,其实就是从Binder中查找Binder是否关联了与描述符相等的IInterface接口:

    1
    2
    3
    4
    5
    6
    public @Nullable IInterface queryLocalInterface(@NonNull String descriptor) {
    if (mDescriptor != null && mDescriptor.equals(descriptor)) {
    return mOwner;
    }
    return null;
    }

如果本地的Binder已经与我们的AIDL接口实现绑定了之后,就直接返回AIDL的实现类,否则,就需要通过代理(这个代理本身也实现了AIDL接口)来连接到Binder。

  • asBinder()方法。返回Binder本身。
  • onTransact()方法。

onTransact()方法就是实现进程间通信的关键方法。这个方法需要四个参数。一个是整型的code,表示需要调用的方法。第二个参数为data,表示远程调用中传入的参数。第三个参数为reply,表示执行后返回的数据。第四个参数为flags,这个参数传入其父类Binder的onTransact方法中,表示RPC的类型。

在onTransact()方法中,如果调用的是AIDL中的方法的时候,就会将返回数据写入reply中。

  • 接下来讲讲代理类Stub.Proxy。

Proxy实现了AIDL接口,其中的AIDL方法是在将参数数据写入data之后,就调用Binder的transact方法,transact方法其实就是调用了onTransact()方法。