[Android AIDL系列 1] 手动编译aidl文件,生成Java、C++[android]、C++[ndk]、Rust接口

2023-11-07

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接口文件。
说明:

  1. aidl使用说明
    aidl --lang={java|cpp|ndk} [options] input_aidl_file。
    在命令行中,aidl不带任何参数,打印使用说明。
  2. –lang={java|cpp|ndk}
    指定生成接口类型。如果不指定,默认生成Java文件。
  3. -o 指定输出目录
    Java:省略-o参数,java文件生成到aidl文件目录下。
    C++/Rust:必选参数。
    为了清除查看效果,指定到单独的目录:-o ./java
  4. -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]接口

  1. 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>

  2. –lang=cpp,参数指定生成Android源码下编译的C++接口文件。

  3. -o和-h参数分别指定.cpp文件和.h文件输出的路径。可以指定不同的目录。
    1)C++接口文件比较多,一个aidl文件生成4个文件。第一步编译IMyServiceCallback.aidl后,生成文件包括:
    3个头文件:
    一个Interface头文件:IMyServiceCallback.h
    一个Bp头文件:BpMyServiceCallback.h
    一个Bn头文件:BnMyServiceCallback.h
    一个源码文件:IMyServiceCallback.cpp

$ 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类似。

$ 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接口文件

  1. –lang=rust指定生成rust后端接口文件。
  2. 只需通过-o参数设置输出路径即可,输出结果和Java类似,一个aidl文件对应一个.rs文件。
  3. 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
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

[Android AIDL系列 1] 手动编译aidl文件,生成Java、C++[android]、C++[ndk]、Rust接口 的相关文章

  • 在一个平台上,对于所有数据类型,所有数据指针的大小是否相同? [复制]

    这个问题在这里已经有答案了 Are char int long 甚至long long 大小相同 在给定平台上 不能保证它们的大小相同 尽管在我有使用经验的平台上它们通常是相同的 C 2011 在线草稿 http www open std
  • 我可以使用 moq Mock 来模拟类而不是接口吗?

    正在经历https github com Moq moq4 wiki Quickstart https github com Moq moq4 wiki Quickstart 我看到它 Mock 一个接口 我的遗留代码中有一个没有接口的类
  • 如何检测表单的任何控件的变化?

    如何检测 C 中表单的任何控件的更改 由于我在一个表单上有许多控件 并且如果表单中的任何控件值发生更改 我需要禁用按钮 我正在寻找一些内置函数 事件处理程序 属性 并且不想为此创建自定义函数 不 我不知道任何时候都会触发任何事件any控制表
  • Qt - ubuntu中的串口名称

    我在 Ubuntu 上查找串行端口名称时遇到问题 如您所知 为了在 Windows 上读取串口 我们可以使用以下代码 serial gt setPortName com3 但是当我在 Ubuntu 上编译这段代码时 我无法使用这段代码 se
  • 如何在 Xaml 文本中添加电子邮件链接?

    我在 Windows Phone 8 应用程序中有一些大文本 我希望其中有电子邮件链接 例如 mailto 功能 这是代码的一部分
  • 在 Samsung Galaxy S5 Android 5.0 上使用 MediaPlayer 加载音频流需要超过 10 秒

    由于更新至 Android 5 0 MediaPlayer 在 Samsung Galaxy S5 上无法正常工作 启动音频流后加载时间超过 10 秒 示例代码 MediaPlayer mPlayer new MediaPlayer Str
  • Azure 辅助角色“请求输入之一超出范围”的内部异常。

    我在辅助角色中调用 CloudTableClient CreateTableIfNotExist 方法 但收到一个异常 其中包含 请求输入之一超出范围 的内部异常 我做了一些研究 发现这是由于将表命名为非法表名引起的 但是 我尝试为我的表命
  • C# HashSet 只读解决方法

    这是示例代码 static class Store private static List
  • 卡片视图 单击卡片移至新活动

    我是 Android 编程新手 正在研究卡片布局 我想知道如何使其可点击 android clickable true android foreground android attr selectableItemBackground 我的卡
  • 外键与独立关系 - Entity Framework 5 有改进吗?

    我读过了several http www ladislavmrnka com 2011 05 foreign key vs independent associations in ef 4 文章和问题 https stackoverflow
  • 如何检查 Android 中的同步设置

    我正在构建一个 Android 应用程序 我需要检查设备中注册的每个单独帐户的同步设置 我知道我可以通过 ContentResolver 类来做到这一点 但我遇到了一些问题 我已设法获取设备上所有帐户的列表 但我不知道在运行时从哪里获取特定
  • 找不到符号 NOTIFICATION_SERVICE?

    package com test app import android app Notification import android app NotificationManager import android app PendingIn
  • “接口”类似于 boost::bind 的语义

    我希望能够将 Java 的接口语义与 C 结合起来 起初 我用过boost signal为给定事件回调显式注册的成员函数 这非常有效 但后来我发现一些函数回调池是相关的 因此将它们抽象出来并立即注册所有实例的相关回调是有意义的 但我了解到的
  • 动态添加 ASP.Net 控件

    我有一个存储过程 它根据数据库中存储的记录数返回多行 现在我想有一种方法来创建 div 带有包含该行值的控件的标记 如果从数据库返回 10 行 则 10 div 必须创建标签 我有下面的代码来从数据库中获取结果 但我不知道如何从这里继续 S
  • 使用 %d 打印 unsigned long long

    为什么我打印以下内容时得到 1 unsigned long long int largestIntegerInC 18446744073709551615LL printf largestIntegerInC d n largestInte
  • Android:如何从网络异步获取搜索建议?

    我创建了一个可搜索的活动 现在 我想添加从网络服务获取的搜索建议 我想异步获取这些建议 根据添加自定义建议 http developer android com guide topics search adding custom sugge
  • 如果没有抽象成员,基类是否应该标记为抽象?

    如果一个类没有抽象成员 可以将其标记为抽象吗 即使没有实际理由直接实例化它 除了单元测试 是的 将不应该实例化的基类显式标记为抽象是合理且有益的 即使在没有抽象方法的情况下也是如此 它强制执行通用准则来使非叶类抽象 它阻止其他程序员创建该类
  • 方法优化 - C#

    我开发了一种方法 允许我通过参数传入表 字符串 列数组 字符串 和值数组 对象 然后使用这些参数创建参数化查询 虽然它工作得很好 但代码的长度以及多个 for 循环散发出一种代码味道 特别是我觉得我用来在列和值之间插入逗号的方法可以用不同的
  • 如何防止在Spring Boot单元测试中执行import.sql

    我的类路径中有一个 import sql 文件 其中包含一些 INSERT 语句 当使用 profile devel 运行我的应用程序时 它的数据被加载到 postgres 数据库中 到目前为止一切正常 当使用测试配置文件执行测试时 imp
  • 有没有任何代码可以在android中设置壁纸而无需裁剪和缩放?

    我正在创建一个画廊应用程序 我的第一个应用程序 这是我的代码 Bitmap bmd BitmapFactory decodeStream is try getApplicationContext setWallpaper bmd catch

随机推荐

  • 将模型显示在ui上

    https blog csdn net ChinarCSDN article details 81058773 ops request misc request id biz id 102 utm term unity E4 B8 AD E
  • 【单目标优化算法】樽海鞘群算法(Matlab代码实现)

    个人主页 研学社的博客 欢迎来到本博客 博主优势 博客内容尽量做到思维缜密 逻辑清晰 为了方便读者 座右铭 行百里者 半于九十 本文目录如下 目录 1 概述 2 运行结果 3 文献来源 4 Matlab代码实现 1 概述 在过去的
  • vmware中centos7启动出现Internal error xfs XFS_WANT_CORRUPTED_GOTO错误

    vmware中centos出现 sda Assuming drive cache write through Internal error xfs XFS WANT CORRUPTED GOTO at line 1692 of file f
  • 怎么写一篇技术笔记

    为什么要写笔记 为什么做笔记 从我们开始上学开始就开始做各种不同笔记 好记性不如烂笔头 做笔记的第一个目的好像就是为了抵抗遗忘 根据艾宾浩斯遗忘曲线 记忆是不断的流逝 只有不定时去补偿记忆 才能能够减缓遗忘的速度 做笔记也是一个对知识点的一
  • RandomAccessFile使用小结

    本文是基于Linux环境运行 读者阅读前需要具备一定Linux知识 RandomAccessFile是Java输入 输出流体系中功能最丰富的文件内容访问类 既可以读取文件内容 也可以向文件输出数据 与普通的输入 输出流不同的是 Random
  • Knife4j 基础(OpenAPI3+SpringBoot2.7)

    1 Knife4j基础 OpenAPI3 SpringBoot2 7 本文按照官方文档 在 SpringBoot 2 7 项目中 集成 Knife4j 的 OpenAPI3 版本 2 官网 Knife4j官网 Knife4j在实现OpenA
  • adb shell后,getevent退出方法

    adb shell后 getevent退出方法 输入 exit 然后回车退出
  • ubuntu 下安装微软字体和 console

    https www cnblogs com feipeng8848 p 9649089 html 转载于 https www cnblogs com zach0812 p 11514680 html
  • SJTU简单路径数目

    Description 大家还记得邻接表类吗 没错 邻接表是表示稀疏图 边数比较少的图 的一种很好的数据结构 现在 我们要求使用深度优先遍历的思想 利用邻接表类 对给定的有向图 找出从指定结点start出发 长度为M的所有简单路径 简单路径
  • 超详细的卷积后大小的计算公式

    计算公式定义 定义几个参数 输入图片大小 W W 卷积核大小 F F 步长 S padding的像素数 P 于是我们可以得出计算公式为 N W F 2P S 1 输出图片大小为 N N 以resnet50为例 输入为 1 3 224 224
  • 手机耳机怎么在电脑上说话_手机耳机怎样当做电脑麦克风?

    首先 这篇文章讲的是有绿粉两个颜色的耳机 麦克接口的电脑 方法一 某宝9 9一条耳机一分二分线器进行解决 注意默认录音设备是否设置对了 方法二 玄学声卡 某些电脑的自带声卡很神奇 可以玄学逆转电流 就比如我家电脑 只要把手机耳机 单线耳机
  • Hive启动报错(个人遇到问题&解决方法)

    hive执行sql报错 FAILED SemanticException org apache hadoop hive ql metadata HiveException java lang RuntimeException Unable
  • C++ 代码换行

    1 字符串太长 换行显示 怎么办 2 使用反斜杠 如下 string str abcd 1234 注意 反斜杠后面不准有任何字符 下一行开头的制表符不包含在整个字符串中 但是下一行开头的空格符包含在整个字符串中 3 使用双引号 如下 str
  • 浅谈关于QT中Webkit内核浏览器

    关于QT中Webkit内核浏览器是本文要介绍的内容 主要是来学习QT中webkit中浏览器的使用 提起WebKit 大家自然而然地想到浏览器 作为浏览器内部的主要构件 WebKit的主要工作是渲染 给定一个HTML文件 WebKit的工作是
  • linux设备管理之设备号与次设备号

    linux设备管理之主设备号与次设备号 jinzi 博客园 剽窃 过来的 记录下 以备查 主设备号和次设备号 一个字符设备或者块设备都有一个主设备号和次设备号 主设备号和次设备号统称为设备号 主设备号用来表示一个特定的驱动程序 次设备号用来
  • 使用 Python 对股票数据分析预测

    使用 Python 对股票数据分析预测 文章目录 使用 Python 对股票数据分析预测 目录索引 模块安装 股票数据获取 雅虎财经 Quandl 模块 Pandas Datareader 模块 数据预处理 缺失值查找 数据规范化 股价涨跌
  • 前端埋点VS后端埋点

    前端埋点比后端埋点更灵活 比如页面停留时间 点击下拉框动作等都可以通过埋点接口让后端记录下来 而后端埋点 这些是记录不下来的 因为没有请求 后端埋点还有一个问题 有可能前端不同按钮调用后端同一个接口 此时后端埋点是区分不出来的 后端埋点又分
  • 代码习惯

    补个liangs333的代码习惯 include
  • 全面 Serverless 化,阿里云微服务引擎 MSE 重磅升级

    微服务已成为企业数字化首选的应用架构 并正在向缩短服务的构建周期和降低资源成本 提升架构质量和架构效率两个方向演进 今天 阿里云正式宣布微服务引擎 MSE 重磅升级 全面 Serverless 化 带来两大新形态和两大新体验 产业新形态 业
  • [Android AIDL系列 1] 手动编译aidl文件,生成Java、C++[android]、C++[ndk]、Rust接口

    AIDL文件在Android系统上应用广泛 和底层的Binder机制紧密关联 在Android源码或者Android Studio中通常是自动编译aidl文件 生成对应语言的接口文件 做应用层Java开发 aidl和binder封装的比较