Skip to content

Latest commit

 

History

History
86 lines (70 loc) · 4.92 KB

File metadata and controls

86 lines (70 loc) · 4.92 KB

Rust 在 Android 系统开发中的应用与调用

概述

Rust 以其内存安全(ownership/borrow)、接近 C++ 的性能和良好的并发模型,逐渐被引入到 Android 应用与系统开发中。无论是在应用层的性能模块(如加密、解析、编解码)还是在平台层(AOSP 的系统服务、HAL、驱动接口)都能看到 Rust 的适用场景。

优势

  • 内存安全:通过语言特性在编译期阻止大量内存错误(空指针、数据竞争、越界等)。
  • 性能:与 C/C++ 相当,适合性能敏感场景。
  • 并发安全:线程与所有权模型有助于构建更安全的并发代码。
  • 现代生态:包管理(Cargo)、丰富的 crate(如 jni、ndk、bindgen)可以提升开发效率。

典型应用场景

  • 性能关键的库:音视频编解码、图像处理、压缩/解压、加密算法实现。
  • 网络与协议栈:高性能、低延迟的网络组件。
  • 安全敏感模块:密码学、证书处理、解析器(XML/JSON/二进制格式)。
  • AOSP 平台组件:替代或补充现有 C/C++ 的系统服务、HAL 实现。

与 Java/Kotlin 的互操作(常见调用方式)

  1. JNI(最常用)

    • 在 Rust 中通过 jni crate 或导出 C ABI 接口(#[no_mangle] pub extern "C")暴露给 Java 层。
    • 推荐使用 jni crate(方便构造 jstring、jobject 等)或 ndk/ndk-glue 系列在 NDK 情况下简化绑定。
  2. C ABI + cbindgen/bindgen

    • 使用 #[no_mangle] extern "C" 导出函数,使用 cbindgen 生成头文件,Java 侧通过 JNI 调用 C 接口。
  3. 通过系统服务(AIDL/Binder)或通过 native library 形式由系统组件加载

    • 在 AOSP 中,可以把 Rust 编译为动态库或直接作为 platform module(见下一节),通过 Binder/AIDL 提供服务接口。

简单示例:Rust 导出 C ABI 并由 Java 调用(概念)

Rust 端:

#[no_mangle]
pub extern "C" fn add(a: i32, b: i32) -> i32 {
	 a + b
}

Java 端:

public class NativeLib {
	 static { System.loadLibrary("mylib"); }
	 public static native int add(int a, int b);
}

更实用的方式是使用 jni crate 来直接操作 JNIEnv、构造/返回 jstring 等。

在 AOSP(Android Open Source Project)中的应用

  • AOSP 自 Android 12 / 13 起开始逐步支持 Rust,Soong 系统加入了对 rust_* 模块的支持(例如 rust_library、rust_binary 等,具体以当前 AOSP 文档为准)。
  • Rust 在 AOSP 中可以用于实现系统服务、平台工具、HAL 等。通常方式:在 Android.bp 中声明 rust 模块或把 Rust 编译产物作为 native library 供 Java/C++ 加载。
  • 注意兼容性:需遵循 AOSP 的 ABI、符号导出规则,以及 Bionic(Android 的 libc)环境下的运行约束。

构建与工具链

  • 本地 Android 应用层(使用 Gradle):可使用 cargo-ndk 或社区的 rust-android-gradle 插件把 Rust 编译为 .so 并自动放入 jniLibs。 示例:
    • 使用 cargo-ndk:
      cargo install cargo-ndk
      cargo ndk -t armeabi-v7a -t arm64-v8a --release build
  • AOSP(平台)中:使用 Soong/Android.bp 中的 Rust 模块支持,或先在外部交叉编译再作为预构建库导入。
  • 常用 crates:jni、ndk、ndk-glue、bindgen、cbindgen。

注意事项与限制

  • 构建复杂度:交叉编译与构建系统集成(Gradle / Soong)需要配置,初期投入较高。
  • ABI 与异常处理:Rust 的 unwinding 与 C++/Java 不同,通常在导出给其他语言的接口处禁用 unwinding 或保证不跨语言抛异常。
  • 二进制体积:增添 Rust 运行时依赖可能使 APK/镜像增大,需要按需裁剪(优化依赖、开启 LTO、去除不必要 feature)。
  • 团队熟悉度:团队需要时间学习 Rust 语法与生态。

推荐实践

  • 小步引入:先把独立、低耦合、性能敏感的模块迁移到 Rust(例如解析器、加密、媒资处理)。
  • 明确边界:通过 C ABI 或 JNI 明确定义 Rust 与 Java/C++ 的边界,尽量减少跨语言调用次数以降低开销与复杂性。
  • 自动化构建:在 CI 中加入交叉编译与多 ABI 的构建验证,确保在不同架构上行为一致。
  • 安全策略:在关键模块(比如安全、网络)优先考虑 Rust,以减少内存缺陷导致的安全风险。

参考资源(快速起步)

  • jni crate 文档:用于在 Rust 中写 JNI 代码。
  • cargo-ndk:帮助把 Rust 库构建为 Android ABI 的 .so。
  • AOSP 文档(搜索 Rust/Soong 支持):查看如何在 Android.bp 中集成 Rust 模块。

以上为在 Android 系统与应用开发中引入 Rust 的概览、优点、调用方式与注意事项。需要的话,我可以:

  • 在仓库中加入一个完整的示例项目(Android app + Rust 动态库);
  • 或补充 AOSP Android.bp 中 rust_library 的实际示例;
  • 或把上面示例展开为可运行的 Gradle + Cargo 配置说明。