添加Gradle依赖
根目录build.gradle.kst文件中添加
1
2
3
4
plugins {
...
id("org.mozilla.rust-android-gradle.rust-android") version "0.9.4" apply false
}
app中引入
1
2
3
4
plugins {
id("org.mozilla.rust-android-gradle.rust-android")
...
}
创建rust项目
这里位置是可选的,主要是创建后位置需要配置正确,我这里模仿c++
,在java同层级创建rust文件夹,然后在rust目录下运行命令
1
cargo new rust-native
然后在app的build.gralde.kts
文件的最外层添加
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
cargo {
module = "src/main/rust/rust-native" // Rust 工程路径
libname = "rust_native" // 编译后的so名字
targets = listOf("x86_64", "arm64") // 目标CPU架构
// profile = "release"
profile = "debug"
}
tasks.configureEach(object : Action<Task> {
override fun execute(task: Task) {
if ((task.name == "javaPreCompileDebug" || task.name == "javaPreCompileRelease")) {
task.setDependsOn(listOf("cargoBuildArm64", "cargoBuildX86_64"))
}
}
})
需要注意,生成的so文件中横线会转化为下划线,所以这里的libname
要写rust_native
,然后model为相对位置
创建jni方法
添加toml依赖
在rust的toml文件中增加
1
2
3
4
5
6
7
8
9
10
[dependencies]
jni = "0.21.1"
[lib]
crate_type = ["rlib", "dylib"]
[features]
default = ["foo"]
foo = []
bar = []
rust jni实现
在rust项目的src目录下创建lib文件,lib文件会编译为so,然后实现一个简单的native方法,类似原始的c++
项目,返回一个字符串
1
2
3
4
5
6
7
8
9
10
11
12
extern crate jni;
use jni::JNIEnv;
use jni::objects::{JClass, JString};
#[no_mangle]
pub extern "C" fn Java_com_jiangker_rust_1jni_RustLib_stringFromJNI<'a>(
env: JNIEnv<'a>,
_class: JClass<'a>,
) -> JString<'a> {
return env.new_string("Rust").unwrap();
}
注意我的安卓项目名称为rust-jni
,所以包名是com.jiangker.rust_jni
,写过c++ jni
应该知道,jni
方法是.
变_
,_
变1
,方法名就如这样
java native方法
1
2
3
4
5
6
7
object RustLib {
external fun stringFromJNI(): String
init {
System.loadLibrary("rust_native")
}
}
使用
1
Greeting(RustLib.stringFromJNI())
我这里创建的默认compose项目,所以这样写
编译运行
cargo增加交叉编译环境
因为我这里只选择了cargoBuildArm64
和cargoBuildX86_64
,所以运行
1
rustup target add aarch64-linux-android
和
1
rustup target add x86_64-linux-android
常见错误
未下载对应环境
下载对应交叉编译环境
运行找不到对应so
编译产物中可以看到so
app产物中无so
可能编译的环境没有对应架构的,需要增加对应架构,支持的架构可以看如下文件 rust-android-gradle/blob/master/plugin/src/main/kotlin/com/nishtahir/RustAndroidPlugin.kt
总结
目前AS对rust在项目上的开发并不友好,不好调试,修改代码我目前都是用RustRover
来编辑的,另外就是相比较c++,这个demo的so库体积要大许多,不过可以用上rust,感觉还是很不错的。