Rust在Android端的入門開發

IOS

上應用還在半路上,遇到了一些整合問題。在瞭解、學習過程中發現,

IOS

Swifit UI

動畫真的是比

Flutter

做的好幾倍,後面有時間可以記錄記錄。本次先記錄

Android

整合吧,對比效能的話,可以在

rust

for

迴圈個

10

萬次,對比

C

的時間消耗。

參考資料

Building and Deploying a Rust library on Android

JNI Create

Create JNI

目錄

Rust在Android端的入門開發

一、環境準備

rustup配置

這個配置,在裝rust的時候就配置了,可以忽略。如果沒有配置,想了解的可以看二、Rust入門之Hello World

配置NDK

第一步

先確定自己的NDK目錄

預設目錄一般都在

/Users/你的使用者名稱/Library/Android/sdk/ndk-bundle

這個位置,使用者目錄可以用

${HOME}

代替。

第二步

建立庫

crate

cargo new android_demo ——lib

第三步

切換到

android_demo

專案下,建立

NDK

檔案

找到

make_standalone_toolchain。py

檔案,執行以下語句

python D:/Android/SDK/ndk-bundle/build/tools/make_standalone_toolchain。py ——api 26 ——arch arm64 ——install-dir NDK/arm64python D:/Android/SDK/ndk-bundle/build/tools/make_standalone_toolchain。py ——api 26 ——arch arm ——install-dir NDK/armpython D:/Android/SDK/ndk-bundle/build/tools/make_standalone_toolchain。py ——api 26 ——arch x86 ——install-dir NDK/x86

對應的

NDK

目錄如下

Rust在Android端的入門開發

第四步

找到

cargo

的配置檔案,

~/。cargo/config

[target。aarch64-linux-android]ar = “E:/VSCodeWorkspace/rust/android_demo/NDK/arm64/bin/aarch64-linux-android-ar”linker = “E:/VSCodeWorkspace/rust/android_demo/NDK/arm64/bin/aarch64-linux-android-clang”[target。armv7-linux-androideabi]ar = “E:/VSCodeWorkspace/rust/android_demo/NDK/arm/bin/arm-linux-androideabi-ar”linker = “E:/VSCodeWorkspace/rust/android_demo/NDK/arm/bin/arm-linux-androideabi-clang”[target。i686-linux-android]ar = “E:/VSCodeWorkspace/rust/android_demo/NDK/x86/bin/i686-linux-android-ar”linker = “E:/VSCodeWorkspace/rust/android_demo/NDK/x86/bin/i686-linux-android-clang”

其中

E:/VSCodeWorkspace/rust/android_demo

是本次專案目錄。

第五步

新增工具鏈

rustup target add aarch64-linux-android armv7-linux-androideabi i686-linux-android

第六步

在當前

android_demo

目錄下,執行以下語句

編譯

Rust

專案,按需要的架構編譯即可。

cargo build ——target aarch64-linux-android ——releasecargo build ——target armv7-linux-androideabi ——releasecargo build ——target i686-linux-android ——release

出現問題

note: %1 不是有效的 Win32 應用程式。 (os error 193) ,第三步和第六步編譯不一致。解決方法:將第四步,換成Android SDK 目錄下的ndk,看下面程式碼示例。error: linker

cc

not found,解決方案也是按照下面,一定要使用 。cmd

解決方案

[target。aarch64-linux-android]ar = “D:\\Android\\SDK\\ndk\\21。4。7075529\\toolchains\\llvm\\prebuilt\\windows-x86_64\\bin\\aarch64-linux-android-ar”linker = “D:\\Android\\SDK\\ndk\\21。4。7075529\\toolchains\\llvm\\prebuilt\\windows-x86_64\\bin\\aarch64-linux-android26-clang。cmd”[target。armv7-linux-androideabi]ar = “D:\\Android\\SDK\\ndk\\21。4。7075529\\toolchains\\llvm\\prebuilt\\windows-x86_64\\bin\\arm-linux-androideabi-ar”linker = “D:\\Android\\SDK\\ndk\\21。4。7075529\\toolchains\\llvm\\prebuilt\\windows-x86_64\\bin\\armv7a-linux-androideabi26-clang++。cmd”xxx

產物

Rust在Android端的入門開發

二、Rust實現

Cargo。toml

[package]name = “android_demo”version = “0。1。0”edition = “2021”# See more keys and their definitions at https://doc。rust-lang。org/cargo/reference/manifest。html[dependencies]jni-sys = “0。3。0”[target。‘cfg(target_os=“android”)’。dependencies]jni = { version = “0。5”, default-features = false }[lib]crate-type = [“dylib”]

lib。rs

/* * @Author: axiong */use std::os::raw::{c_char};use std::ffi::{CString, CStr};#[no_mangle]pub extern fn rust_greeting(to: *const c_char) -> *mut c_char { let c_str = unsafe { CStr::from_ptr(to) }; let recipient = match c_str。to_str() { Err(_) => “there”, Ok(string) => string, }; CString::new(“Hello ”。to_owned() + recipient)。unwrap()。into_raw()}/// Expose the JNI interface for android below/// 只有在目標平臺是Android的時候才開啟 [cfg(target_os=“android”)/// 由於JNI要求駝峰命名,所以要開啟 allow(non_snake_case)#[cfg(target_os=“android”)]#[allow(non_snake_case)]pub mod android { extern crate jni; use super::*; use self::jni::JNIEnv; use self::jni::objects::{JClass, JString}; use self::jni::sys::{jstring}; #[no_mangle] pub unsafe extern fn Java_com_rjx_rustdemo_RustGreeting_greeting(env: JNIEnv, _: JClass, java_pattern: JString) -> jstring { // Our Java companion code might pass-in “world” as a string, hence the name。 let world = rust_greeting(env。get_string(java_pattern)。expect(“invalid pattern string”)。as_ptr()); // Retake pointer so that we can use it below and allow memory to be freed when it goes out of scope。 let world_ptr = CString::from_raw(world); let output = env。new_string(world_ptr。to_str()。unwrap())。expect(“Couldn‘t create java string!”); output。into_inner() }}

三、Android整合

SO整合

Rust在Android端的入門開發

RustGreeting。java

public class RustGreeting { static { System。loadLibrary(“android_demo”); } private static native String greeting(final String pattern); public static String sayHello(String to) { return greeting(to); }}

MainActivity。java

public class MainActivity extends AppCompatActivity { // Used to load the ’native-lib‘ library on application startup。 static { //System。loadLibrary(“native-lib”); } private ActivityMainBinding binding; @Override protected void onCreate(Bundle savedInstanceState) { super。onCreate(savedInstanceState); binding = ActivityMainBinding。inflate(getLayoutInflater()); setContentView(binding。getRoot()); // Example of a call to a native method TextView tv = binding。sampleText; tv。setText(RustGreeting。sayHello(“Rust!!”)); }}

效果

Rust在Android端的入門開發

作者:CodeOver

連結:https://juejin。cn/post/7170696817682694152