【Rust NDK】得想办法Log它一下

265 阅读2分钟

引言

这篇文章介绍一下 jni-rs 这个 crates 和我在使用过程中遇到的一些问题,以及它和常规C/C++编码方式的一些不同。

开发环境

操作系统:Windows 11

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

正文

在android开发中,我们常常通过Log去观察应用的日志信息,对于ndk开发也一样。

创建Rust项目

首先需要创建一个 rust lib 项目 example_2

image.png

然后,为 Cargo.toml 配置 jni-rscargo-ndk

image.png

完成后,就打开 lib.rs 编写逻辑了。

image.png

上图,我们提供了一个 com.example.RustLog#log 测试方法,然后通过它去调用封装后的 android_log 方法。

android_log 方法的实现也很简单,就是通过 env 对象去查找 android.util.Log 类,最后去调用它的 println 方法。

完成后,我们通过命令行编译出 so 文件。

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

image.png

创建Android项目

接下来,创建 Example2 Android 项目测试一下这个so。

image.png

这里,我用 @JavaStatic 注解将 log 方法直接导出到 Java层,这样就省去了 Companion 的包装。

然后,修改 MainActivity 类文件,调用测试。

image.png

最后,别忘了在 buiud.gradle.kts 中增加。

image.png

结果展示

image.png

还有高手?

你以为完了?不不不。

接下来让我们回到 Rust 项目中,看看另外一种 call_method

先贴一下图

image.png

我们通过 jni-rs 提供的 call_static_method 函数,可以直接调用某个类的静态方法。

但对比C/C++的实现来说,在C/C++中,通常需要先找到某个方法的 method_id 最后通过method_id去调用这个方法。

同样的,jni-rs 也提供了获取 method_id 的方法,看图。

image.png

而对于通过 method_id 去调用方法,jni-rs 会默认它为不安全的,也就是unsafe

所以就需要我们通过 unsafe{ ... } 作用域去包裹 call_static_method_unchecked 的执行。

最后,我们说一下 JValue::from,由于 JValue 枚举实现了 From 这个trait。因此,上面的逻辑也可以改为以下这种写法。

image.png

本篇完。