【Rust NDK】开篇

475 阅读4分钟

引言

最近在看Rust相关的东西,于是很无聊的写下了这篇文章,作为 Rust NDK 的接入笔记,也包括在过程中踩的坑。

开发环境

操作系统:Windows 11

编码软件:Visual Studio Code 1.93.1 | Android Studio Ladybug | 2024.2.1 Beta 1

环境搭建

当你阅读本文时,默认你已经配置好了相关环境变量;如果没有,请自行搜索阅读相关文章。

正文

Rust社区提供了两个 crates 来支持和简化 NDK 的开发,它们分别为:

本文的案例也是建立在这两个 crates 的基础上。

创建Rust项目

按照 rust lib 的常规创建逻辑,我们首先在工作目录下Rust lib项目,然后再将它进行ndk改造。

image.png

上述命令行操作后就已经成功在 vscode 中打开了 example_1 项目。

image.png

接下来,我们需要修改这个lib项目的 Cargo.toml,添加上面提到的两个crates,添加完成后应该是下面这个样子。

image.png

上图分别基于 cargo-ndk examplejni-rs example 修改。

然后,就是对so编译打包的相关工具链的安装了。

参考 cargo-ndk 的文档,我们需要执行以下命令行来进行目标工具链的安装

rustup target add aarch64-linux-android armv7-linux-androideabi x86_64-linux-android i686-linux-android

下图是我已经安装成功后的截图。

image.png

至此,该lib项目便能够正常编写NDK相关逻辑了。

接下来,我们打开项目中的 lib.rs 源代码文件,编写一段简单的 rust ndk 代码实现。

image.png

逻辑编写完成后,通过 cargo-ndk 提供的 docs 文档执行以下命令进行 so 文件的编译和打包。

cargo ndk -t armeabi-v7a -t arm64-v8a -o ./jniLibs build --release

上述命令只打包了 armeabi-v7aarm64-v8a 两个so文件,如果需要其他架构,可以自行增加参数。

image.png

编译打包命令完成后,项目目录就会产出jniLibs文件夹和对应架构的so文件。

创建Android项目

接下来,我们创建android项目Example1来进行测试。

image.png

我们将编译后的产物连同 jniLibs 目录一起放入 app/src/main 目录下,然后编写对应的 JNI 接口类和方法。

这里需要注意的是,如果是静态实现(static)使用kotlin的伴生对象,包括 object RustJNI { ... } 则需要在方法上增加 @JvmStatic 注解来将 add 方法直接暴露给Java,否则你就需要修改 JNI中的方法签名,以下是崩溃截图。

image.png

这时候就需要修改 JNI 方法签名了。

image.png

言归正传,接下来修改 MainActivity ,来调用这个JNI方法。

image.png

然后,我们需要在 build.gradkle.kts 中增加

image.png

如果没有上图的 ndk{ ... } 那么你大概率在 Run 时会崩溃。

得到一个崩溃异常:java.lang.UnsatisfiedLinkError

结果展示

最后,通过点击按钮后,得到 1+2 的值。

image.png

至此,开篇结束。