建网站的手机软件,房山区做网站,哈尔滨开发网站,网页制作网站建设实战大全Andorid调用Rust 目前Rust在移动端上的应用#xff0c;一般作为应用sdk的提供#xff0c;供各端使用#xff0c;目前飞书底层使用Rust编写通用组件。 该篇适合对Android、Rust了解#xff0c;想看如何做整合#xff0c;如果想要工程源码#xff0c;可以评论或留言有解疑…
Andorid调用Rust 目前Rust在移动端上的应用一般作为应用sdk的提供供各端使用目前飞书底层使用Rust编写通用组件。 该篇适合对Android、Rust了解想看如何做整合如果想要工程源码可以评论或留言有解疑也可进行询问更多最新文章也可关注微信公号良技漫谈
一开发环境 确保rust开发环境推荐官方文档, 安装即可 Android相关开发环境需要NDK的下载安装 环境变量的配置为命令行使用提供全局环境
开发工具
1. 如果对android studio比较熟悉可安装rust插件 安装完毕对Rust Toolchain 位置进行配置确认否则可能对rs文件无法识别就无法愉快使用studio编写rust
2. 推荐使用VSCode编写rust代码,可以去下载 Visual Studio Code然后安装rust相关插件即可。
二创建Android工程: • 如果对Android比较熟悉使用studio来创建工程和其他Android工程创建一样创建Empty Activity工程名 AndroidIntegratingRust 先编译通过该空工程确保依赖资源下载完整。
三添加rust lib库 进入到刚创建的AndroidIntegratingRust工程下
1.使用rust Cargo创建 lib库
Cargo new rust_lib --lib • 创建成功后会有rust_lib库结构如下
├── 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库依赖, https://crates.io/地址下确认版本, create-type 填写cdylib 动态链接库
[lib]
name rust_lib
crate-type [cdylib][dependencies]
jni 0.20.0 3.配置要编译so的linker及target 这个在rust_lib下创建.cargo目录添加config.toml配置文件 填入linker对应的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文档。 准备编译rust代码为so的环境已经准备完
四编写Android和Rust代码 创建Android代码, RustGreetings类 使用kotlin所以用external声明JNI函数
class RustGreetings {fun sayHello(to: String): String {return greeting(to)}companion object {JvmStatic external fun greeting(pattern: String): String}
} 在Rust lib库下编写对应的JNI函数映射从create.io下可以看到有关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 GCd.
use jni::objects::{JClass, JString};// This is just a pointer. Well be returning it from our function. We
// cant return one of the objects with lifetime information because the
// lifetime checker wont 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. Its 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(Couldnt 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(Couldnt 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 编译之前确认之前rust环境是可以使用的了且要看下rustup target 下是否已经有要交叉编译的工具了。 rustc --print target-list | grep android 可以查看相关android 交叉编译工具,我们demo之前在配置target时使用了32和64位的ARM CPU 架构linker
aarch64-linux-android
arm-linux-androideabi
armv7-linux-androideabi
i686-linux-android
thumbv7neon-linux-androideabi
x86_64-linux-android 如果没有安装需要安装下对应的
rustup target add aarch64-linux-android armv7-linux-androideabi rustup show 可以看到当前rust开发语言环境包括 installed targets for active toolchain rustup target list可以查看到那些已经安装和rust支持的。
执行编译 到rust_lib目录下执行编译
cargo build --target aarch64-linux-android --release编译成功到target目录下release下去查看对应的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代码运行工程 sourceSets {main {jniLibs.srcDirs [src/main/libs]}} copy 对应的so文件到 Android工程下src/main/libs下 在Android工程下build.gradle下记得引用so为jniLibs PS: 也欢迎大家评论和交流~ 更多文章也可关注微信公号良技漫谈