AIDL文件在Android系统上应用广泛,和底层的Binder机制紧密关联。
在Android源码或者Android Studio中通常是自动编译aidl文件,生成对应语言的接口文件。
做应用层Java开发,aidl和binder封装的比较“干净”,不用太多的涉及binder的调用细节,也不用太关心aidl的编译过程。
如果是做中下层开发,包括framework、native层开发,可能需要编写native service,有必要理解binder的底层机制。
先从编译aidl开始。这里只说明编译aidl生成各种类型后端接口文件的过程。生成的接口文件内容再写文章单独介绍。
以下演示是在Ubuntu系统上测试的。
一、准备
1. aidl编译工具
即aidl命令,Android sdk或者Android源码中都有。
sdk中aidl,需要把路径添加到path中。
位置:~/Android/Sdk/build-tools/33.0.2/aidl
源码中aidl,设置源码编译环境后,自动添加到path中。
位置:out/soong/host/linux-x86/bin/aidl
2. 演示用的aidl文件
写2个简单的aidl文件,一个是服务接口,一个是回调接口。可用覆盖大部分的实际场景。
文件目录结构和文件内容如下。
$ tree .
.
└── aidl
└── com
└── my
└── pkg
├── IMyServiceCallback.aidl
└── IMyServiceInterface.aidl
回调接口定义:
// IMyServiceCallback.aidl
package com.my.pkg;
interface IMyServiceCallback {
void onEvent(int code, String message);
}
服务接口定义:
// IMyServiceInterface
package com.my.pkg;
interface IMyServiceInterface {
int doSomething(in String str, int num);
void setCallBack(com.my.pkg.IMyServiceCallback callback);
}
二、生成Java接口
执行如下命令,生成Java接口文件。
说明:
- aidl使用说明
aidl --lang={java|cpp|ndk} [options] input_aidl_file。
在命令行中,aidl不带任何参数,打印使用说明。 - –lang={java|cpp|ndk}
指定生成接口类型。如果不指定,默认生成Java文件。 - -o 指定输出目录
Java:省略-o参数,java文件生成到aidl文件目录下。
C++/Rust:必选参数。
为了清除查看效果,指定到单独的目录:-o ./java - -I DIR, --include=DIR
import搜索路径,指定依赖的aidl文件所在目录。不是C++头文件目录。
例如:IMyServiceInterface.aidl引用了IMyServiceCallback.aidl,在生成IMyServiceInterface.aidl的时候需要指定-I参数才能正常编译。
只要是AIDL文件中有依赖,生成任何类型的接口(Java、C++、Rust)都要指定这个参数。
# 前2条命令效果相同,不指定--lang参数,默认生成Java文件
$ aidl -o ./java --lang=java aidl/com/my/pkg/IMyServiceCallback.aidl
$ aidl -o ./java aidl/com/my/pkg/IMyServiceCallback.aidl
$ aidl -I ./aidl/ -o ./java aidl/com/my/pkg/IMyServiceInterface.aidl
$ tree
.
├── aidl
│ └── com
│ └── my
│ └── pkg
│ ├── IMyServiceCallback.aidl
│ └── IMyServiceInterface.aidl
└── java
└── com
└── my
└── pkg
├── IMyServiceCallback.java
└── IMyServiceInterface.java
三、生成C++[Android]接口
-
cpp和ndk的区别
cpp:生成的代码是为了在Android源码中编译,代码中会调用Android源码中的native接口。
例如,引用的头文件:
<binder/IBinder.h>,<binder/IInterface.h>,<binder/Status.h>,<android-base/macros.h>ndk:生成的代码是为了使用ndk独立编译,调用的是ndk的接口,
例如,引用的头文件:
<android/binder_interface_utils.h> <android/binder_ibinder.h> -
–lang=cpp,参数指定生成Android源码下编译的C++接口文件。
-
-o和-h参数分别指定.cpp文件和.h文件输出的路径。可以指定不同的目录。
1)C++接口文件比较多,一个aidl文件生成4个文件。第一步编译IMyServiceCallback.aidl后,生成文件包括:
3个头文件:
一个Interface头文件:IMyServiceCallback.h
一个Bp头文件:BpMyServiceCallback.h
一个Bn头文件:BnMyServiceCallback.h
一个源码文件:IMyServiceCallback.cpp文章来源:https://www.toymoban.com/news/detail-478191.html
$ aidl -h ./cpp_android/ -o ./cpp_android --lang=cpp aidl/com/my/pkg/IMyServiceCallback.aidl
$ tree
.
├── aidl
│ └── com
│ └── my
│ └── pkg
│ ├── IMyServiceCallback.aidl
│ └── IMyServiceInterface.aidl
└── cpp_android
└── com
└── my
└── pkg
├── BnMyServiceCallback.h
├── BpMyServiceCallback.h
├── IMyServiceCallback.cpp
└── IMyServiceCallback.h
$ aidl -I ./aidl/ -h ./cpp_android/ -o ./cpp_android --lang=cpp aidl/com/my/pkg/IMyServiceInterface.aidl
$ tree
.
├── aidl
│ └── com
│ └── my
│ └── pkg
│ ├── IMyServiceCallback.aidl
│ └── IMyServiceInterface.aidl
└── cpp_android
└── com
└── my
└── pkg
├── BnMyServiceCallback.h
├── BnMyServiceInterface.h
├── BpMyServiceCallback.h
├── BpMyServiceInterface.h
├── IMyServiceCallback.cpp
├── IMyServiceCallback.h
├── IMyServiceInterface.cpp
└── IMyServiceInterface.h
四、生成C++[ndk]接口
除了–lang=ndk指定生成ndk后端接口,过程和结果都和cpp类似。文章来源地址https://www.toymoban.com/news/detail-478191.html
$ aidl -I ./aidl/ -h ./cpp_ndk -o ./cpp_ndk --lang=ndk aidl/com/my/pkg/IMyServiceInterface.aidl
$ aidl -h ./cpp_ndk -o ./cpp_ndk --lang=ndk aidl/com/my/pkg/IMyServiceCallback.aidl
$ tree cpp_*
cpp_android
└── com
└── my
└── pkg
├── BnMyServiceCallback.h
├── BnMyServiceInterface.h
├── BpMyServiceCallback.h
├── BpMyServiceInterface.h
├── IMyServiceCallback.cpp
├── IMyServiceCallback.h
├── IMyServiceInterface.cpp
└── IMyServiceInterface.h
cpp_ndk
├── aidl
│ └── com
│ └── my
│ └── pkg
│ ├── BnMyServiceCallback.h
│ ├── BnMyServiceInterface.h
│ ├── BpMyServiceCallback.h
│ ├── BpMyServiceInterface.h
│ ├── IMyServiceCallback.h
│ └── IMyServiceInterface.h
└── com
└── my
└── pkg
├── IMyServiceCallback.cpp
└── IMyServiceInterface.cpp
五、生成Rust接口文件
- –lang=rust指定生成rust后端接口文件。
- 只需通过-o参数设置输出路径即可,输出结果和Java类似,一个aidl文件对应一个.rs文件。
- Rust后端是比较新版本的aidl才支持的,可能是Android 12以后,可以查看aidl命令帮助确认。
$ aidl -o ./rust --lang=rust aidl/com/my/pkg/IMyServiceCallback.aidl
$ aidl -I ./aidl/ -o ./rust --lang=rust aidl/com/my/pkg/IMyServiceInterface.aidl
$ tree
.
├── aidl
│ └── com
│ └── my
│ └── pkg
│ ├── IMyServiceCallback.aidl
│ └── IMyServiceInterface.aidl
└── rust
└── com
└── my
└── pkg
├── IMyServiceCallback.rs
└── IMyServiceInterface.rs
到了这里,关于[Android AIDL系列 1] 手动编译aidl文件,生成Java、C++[android]、C++[ndk]、Rust接口的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!