IOS
上應用還在半路上,遇到了一些整合問題。在瞭解、學習過程中發現,
IOS
的
Swifit UI
動畫真的是比
Flutter
做的好幾倍,後面有時間可以記錄記錄。本次先記錄
Android
整合吧,對比效能的話,可以在
rust
中
for
迴圈個
10
萬次,對比
C
的時間消耗。
參考資料
Building and Deploying a Rust library on Android
JNI Create
Create JNI
目錄
一、環境準備
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
目錄如下
第四步
找到
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實現
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整合
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!!”)); }}
效果
作者:CodeOver
連結:https://juejin。cn/post/7170696817682694152