文章目录
前言
一、分析 AIDL 文件生成的 Java 源文件
1、IMyAidlInterface.java 中的类结构
2、DESCRIPTOR 描述符
3、Stub 构造方法
4、Stub.asInterface 方法
5、Stub.onTransact 方法
6、Stub.Proxy 代理类
前言
在上一篇博客 【Binder 机制】AIDL 分析 ( 创建 AIDL 文件 | 创建 Parcelable 类 | AIDL 中使用 Parcelable 类 | 编译工程生成 AIDL 对应的Java源文件 ) 创建了 AIDL 文件 , 并编译生成了 AIDL 文件对应的 Java 源文件 , 现在开始分析生成在 " AIDL_Demo\app\build\generated\aidl_source_output_dir\debug\out\kim\hsl\aidl_demo " 目录 中的 " IMyAidlInterface.java " 源文件 ;
一、分析 AIDL 文件生成的 Java 源文件
分析 【Binder 机制】AIDL 分析 ( 创建 AIDL 文件 | 创建 Parcelable 类 | AIDL 中使用 Parcelable 类 | 编译工程生成 AIDL 对应的Java源文件 ) 二、编译工程生成 AIDL 文件对应的 Java 源文件 2、生成的 AIDL 对应 Java 源文件 章节中 , 编译 AIDL 文件生成的源码 ;
1、IMyAidlInterface.java 中的类结构
生成的类是 IMyAidlInterface.java , 继承了 android.os.IInterface 接口 ;
public interface IMyAidlInterface extends android.os.IInterface
其中定义了两个内部类 ,
内部类 1 11 如下 : IMyAidlInterface 的默认实现 ;
/** Default implementation for IMyAidlInterface. */ public static class Default implements kim.hsl.aidl_demo.IMyAidlInterface
内部类 2 22 如下 : IPC 机制的本地实现 ;
/** Local-side IPC implementation stub class. */ public static abstract class Stub extends android.os.Binder implements kim.hsl.aidl_demo.IMyAidlInterface
2、DESCRIPTOR 描述符
在 Stub 内部类中 , 定义的常量 DESCRIPTOR 是 AIDL 文件的 " 包名.类名 " , 用于查找 Binder 用的 ;
private static final java.lang.String DESCRIPTOR = "kim.hsl.aidl_demo.IMyAidlInterface";
3、Stub 构造方法
Stub 的构造方法中 , 调用了 Binder 的 attachInterface 方法 , 传入了 AIDL 文件的全类名 ; 作用是将该 AIDL 接口与 Binder 进行关联 ;
/** Construct the stub at attach it to the interface. */ public Stub() { this.attachInterface(this, DESCRIPTOR); }
4、Stub.asInterface 方法
Stub 中定义了 asInterface 方法 , 该方法的作用是将 android.os.IBinder 对象转为 AIDL 接口对象 ; 传入的 DESCRIPTOR 描述符 , 用于描述用户想要哪个 Binder , android.os.IBinder 对象调用 queryLocalInterface 方法 , 检查本地服务是否存在 ;
如果可以找到本地服务对应的接口 , 可以直接返回本地服务 ;
如果没有找到本地服务 , 就会返回一个 Stub 代理 ;
详细的过程参考下面的代码 :
/** * 将IBinder对象强制转换为kim.hsl.aidl_demo.IMyAidlInterface接口,必要时生成代理。 */ public static kim.hsl.aidl_demo.IMyAidlInterface asInterface(android.os.IBinder obj) { if ((obj==null)) { return null; } // 传入 DESCRIPTOR 描述符 , 用于描述用户想要哪个 Binder // android.os.IBinder 对象调用 queryLocalInterface 方法 , 检查本地服务 android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR); // 如果可以找到本地服务对应的接口 , 可以直接返回本地服务 if (((iin!=null)&&(iin instanceof kim.hsl.aidl_demo.IMyAidlInterface))) { return ((kim.hsl.aidl_demo.IMyAidlInterface)iin); } // 如果没有找到本地服务 , 就会返回一个 Stub 代理 return new kim.hsl.aidl_demo.IMyAidlInterface.Stub.Proxy(obj); }
IBinder 是一个接口 , 其中定义了一堆常量标识符 ;
transact 方法对应 Binder 底层发起 IPC 的请求函数 ;
public interface IBinder { /** * 对对象执行常规操作。 * * @param code 要执行的操作。 * 这应该是介于{@link #FIRST_CALL_TRANSACTION}和{@link #LAST_CALL_TRANSACTION}之间的数字。 * @param data 要发送到目标的封送数据。不能为null。 * 如果不发送任何数据,则必须创建此处给出的空地块。 * @param reply 要从目标接收的封送数据。如果您对返回值不感兴趣,则可能为null。 * @param flags 其他操作标志。正常RPC为0,单向RPC为{@link#FLAG_ONEWAY}。 * * @return 从{@link Binder#onTransact}返回结果。成功的调用通常返回true;false通常表示未理解事务代码。 */ public boolean transact(int code, @NonNull Parcel data, @Nullable Parcel reply, int flags) throws RemoteException; }