Rust在Android端集成使用詳解
Andorid調(diào)用Rust
- 目前Rust在移動(dòng)端上的應(yīng)用,一般作為應(yīng)用sdk的提供,供各端使用,目前飛書底層使用Rust編寫通用組件。
- 該篇適合對(duì)Android、Rust了解,想看如何做整合,如果想要工程源碼,可以評(píng)論或留言有解疑也可進(jìn)行詢問(更多最新文章也可關(guān)注微信公號(hào):良技漫談)
一.開發(fā)環(huán)境:
- 確保rust開發(fā)環(huán)境,推薦官方文檔, 安裝即可
- Android相關(guān)開發(fā)環(huán)境,需要NDK的下載安裝
- 環(huán)境變量的配置,為命令行使用提供全局環(huán)境
開發(fā)工具:
1. 如果對(duì)android studio比較熟悉,可安裝rust插件

安裝完畢,對(duì)Rust Toolchain 位置進(jìn)行配置確認(rèn),否則可能對(duì)rs文件無法識(shí)別,就無法愉快使用studio編寫rust
2. 推薦使用VSCode編寫rust代碼,可以去下載 Visual Studio Code,然后安裝rust相關(guān)插件即可。
二.創(chuàng)建Android工程:
• 如果對(duì)Android比較熟悉,使用studio來創(chuàng)建工程,和其他Android工程創(chuàng)建一樣,創(chuàng)建Empty Activity,工程名 AndroidIntegratingRust
先編譯通過該空工程,確保依賴資源下載完整。
三,添加rust lib庫(kù):
進(jìn)入到剛創(chuàng)建的AndroidIntegratingRust工程下
1.使用rust Cargo創(chuàng)建 lib庫(kù):
Cargo new rust_lib --lib
• 創(chuàng)建成功后會(huì)有rust_lib庫(kù),結(jié)構(gòu)如下:
├── app │ ├── build │ ├── build.gradle │ ├── libs │ ├── proguard-rules.pro │ └── src ├── build │ └── kotlin ├── build.gradle ├── gradle │ └── wrapper ├── gradle.properties ├── gradlew ├── gradlew.bat ├── local.properties ├── rust_lib //位置在這 │ ├── Cargo.lock │ ├── Cargo.toml │ ├── src │ └── target └── settings.gradle
2.編輯Cargo.toml
輸入目前需要的jni庫(kù)依賴, https://crates.io/地址下確認(rèn)版本, create-type 填寫cdylib 動(dòng)態(tài)鏈接庫(kù)
[lib] name = "rust_lib" crate-type = ["cdylib"] [dependencies] jni = "0.20.0"
3.配置要編譯so的linker及target
- 這個(gè)在rust_lib下創(chuàng)建.cargo目錄,添加config.toml配置文件
- 填入linker對(duì)應(yīng)的ndk地址:
[target.aarch64-linux-android] linker = "/Users/android-sdk-macosx/ndk-bundle/toolchains/llvm/prebuilt/darwin-x86_64/bin/aarch64-linux-android21-clang++" [target.armv7-linux-androideabi] linker = "/Users/android-sdk-macosx/ndk-bundle/toolchains/llvm/prebuilt/darwin-x86_64/bin/armv7a-linux-androideabi21-clang++"
ps: 這是我的mac上ndk所在位置,參考Android官方ndk文檔。
準(zhǔn)備編譯rust代碼為so的環(huán)境已經(jīng)準(zhǔn)備完
四,編寫Android和Rust代碼:
創(chuàng)建Android代碼, RustGreetings類, 使用kotlin所以用external聲明JNI函數(shù)
class RustGreetings {
fun sayHello(to: String): String {
return greeting(to)
}
companion object {
@JvmStatic external fun greeting(pattern: String): String
}
}在Rust lib庫(kù)下,編寫對(duì)應(yīng)的JNI函數(shù)映射,從create.io下可以看到有關(guān)JNI的使用,代碼如下
use jni::JNIEnv;
// These objects are what you should use as arguments to your native
// function. They carry extra lifetime information to prevent them escaping
// this context and getting used after being GC'd.
use jni::objects::{JClass, JString};
// This is just a pointer. We'll be returning it from our function. We
// can't return one of the objects with lifetime information because the
// lifetime checker won't let us.
use jni::sys::jstring;
// This keeps Rust from "mangling" the name and making it unique for this
// crate.
#[no_mangle]
pub extern "system" fn Java_com_android_integratingrust_RustGreetings_greeting(
env: JNIEnv,
// This is the class that owns our static method. It's not going to be used,
// but still must be present to match the expected signature of a static
// native method.
class: JClass,
input: JString,
) -> jstring {
// First, we have to get the string out of Java. Check out the `strings`
// module for more info on how this works.
let mut input: String = env
.get_string(input)
.expect("Couldn't get java string!")
.into();
input = append_string(&input);
// Then we have to create a new Java string to return. Again, more info
// in the `strings` module.
let output = env
.new_string(format!("Hello, {}!", input))
.expect("Couldn't create java string!");
// Finally, extract the raw pointer to return.
output.into_raw()
}
//============== rust code ===============
fn append_string(value: &str) -> String {
let mut origin = String::from(value);
origin.push_str("this is Rust");
return origin;
}
五,編譯Rust代碼為so
- 編譯之前確認(rèn)之前rust環(huán)境是可以使用的了,且要看下rustup target 下是否已經(jīng)有要交叉編譯的工具了。
- rustc --print target-list | grep android 可以查看相關(guān)android 交叉編譯工具,(我們demo之前在配置target時(shí),使用了32和64位的ARM CPU 架構(gòu)linker)
aarch64-linux-android arm-linux-androideabi armv7-linux-androideabi i686-linux-android thumbv7neon-linux-androideabi x86_64-linux-android
如果沒有安裝,需要安裝下對(duì)應(yīng)的
rustup target add aarch64-linux-android armv7-linux-androideabi
- rustup show 可以看到當(dāng)前rust開發(fā)語言環(huán)境,包括 (installed targets for active toolchain)
- rustup target list可以查看到那些已經(jīng)安裝和rust支持的。
執(zhí)行編譯
到rust_lib目錄下執(zhí)行編譯
cargo build --target aarch64-linux-android --release
編譯成功到target目錄下release下去查看對(duì)應(yīng)的so文件
.
├── CACHEDIR.TAG
├── aarch64-linux-android
│ ├── CACHEDIR.TAG
│ └── release
├── armv7-linux-androideabi
│ ├── CACHEDIR.TAG
│ └── release
├── debug
│ ├── build
│ ├── deps
│ ├── examples
│ └── incremental
└── release
├── build
├── deps
├── examples
└── incremental六,使用rust代碼運(yùn)行工程
sourceSets {
main {
jniLibs.srcDirs = ['src/main/libs']
}
}- copy 對(duì)應(yīng)的so文件到 Android工程下src/main/libs下
- 在Android工程下build.gradle下記得引用so為jniLibs
到此這篇關(guān)于Rust在Android端集成使用介紹的文章就介紹到這了,更多相關(guān)Rust Android集成使用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Rust使用Sqlx連接Mysql的實(shí)現(xiàn)
數(shù)據(jù)庫(kù)在編程中是一個(gè)很重要的環(huán)節(jié),本文主要介紹了Rust使用Sqlx連接Mysql的實(shí)現(xiàn),記錄rust如何操作數(shù)據(jù)庫(kù)并以mysql為主的做簡(jiǎn)單的使用說明,感興趣的可以了解一下2024-03-03
Rust 堆內(nèi)存指針 Box的實(shí)現(xiàn)示例
在 Rust 中,Box<T>是最基礎(chǔ)、最簡(jiǎn)潔的智能指針,核心作用是將數(shù)據(jù)從棧內(nèi)存轉(zhuǎn)移到堆內(nèi)存,并通過獨(dú)占所有權(quán)機(jī)制管理堆內(nèi)存的分配與釋放,下面就來詳細(xì)的介紹一下,感興趣的可以了解一下2026-04-04

