Android集成Rust

  1. 一、Android环境
  2. 二、Rust环境
  3. 三、Gradle部分
    1. 根目录的build.gradle
    2. 模块build.gradle
  4. 四、Cargo部分
  5. 五、代码编译
  6. 六、代码测试
    1. Java
    2. Rust

主要使用了[rust-android-gradle]https://github.com/mozilla/rust-android-gradle来集成rust开发环境。

一、Android环境

不多说,开发Andorid的环境Android StudioNDK环境准备。

二、Rust环境

  • 安装本地Rust开发环境。
  • 安装Android对应rust工具链
    rustup target add armv7-linux-androideabi   # for arm
    rustup target add i686-linux-android # for x86
    rustup target add aarch64-linux-android # for arm64
    rustup target add x86_64-linux-android # for x86_64
    rustup target add x86_64-unknown-linux-gnu # for linux-x86-64
    rustup target add x86_64-apple-darwin # for darwin x86_64 (if you have an Intel MacOS)
    rustup target add aarch64-apple-darwin # for darwin arm64 (if you have a M1 MacOS)
    rustup target add x86_64-pc-windows-gnu # for win32-x86-64-gnu
    rustup target add x86_64-pc-windows-msvc # for win32-x86-64-msvc
    ...

三、Gradle部分

根目录的build.gradle

buildscript {
repositories {
maven {
url "https://plugins.gradle.org/m2/"
}
}
dependencies {
classpath 'org.mozilla.rust-android-gradle:plugin:0.9.2'
}
}

或者

buildscript {
//...
}

plugins {
id "org.mozilla.rust-android-gradle.rust-android" version "0.9.2"
}

模块build.gradle

apply plugin: 'org.mozilla.rust-android-gradle.rust-android'

cargo {
module = "./src/main/rust/myrust" // Cargo.toml路径
libname = "myrust" // Cargo.toml 中 [package] 中 name
targets = ["arm64","arm","x86","x86_64"]
}

四、Cargo部分

在指定配置的module目录下添加我们的项目

cargo new --lib myrust

libname要和Cargo.toml里指定的包名一致。
[package]
name = "myrust"
version = "0.1.0"
edition = "2021"

[dependencies]
jni = "0.5.2"

[lib]
name = "myrust"
crate_type = ["staticlib", "dylib"]

五、代码编译

需要在项目的根目录下运行命令

./gradlew cargoBuild

或者在build.gradle中添加下面代码:
tasks.whenTaskAdded { task ->
if ((task.name == 'javaPreCompileDebug' || task.name == 'javaPreCompileRelease')) {
task.dependsOn 'cargoBuild'
}
}

通过上面的方式,可以在编译结束后看到在下面两个地方分别生成了功能的so包:
github

便完成了rust编译成so文件。

六、代码测试

Java

static {
System.loadLibrary("myrust");
}

public native int test1(int a);

Rust

extern crate jni;

use jni::JNIEnv;
use jni::objects::JClass;

#[no_mangle]
#[allow(non_snake_case)]
pub extern "C" fn Java_com_yang_rust_Test_test1(_env: JNIEnv, _class: JClass, _a: i32) -> i32 {
3
}