Rust 学习指南 - 使用Rust开发Android库

4,933 阅读2分钟
原文链接: www.codemore.top

设置开发环境

在开始开发之前首先需要初始化Rust的开发环境,对于Android开发环境可以下载Android Studio 会自动配置,然后在环境变量设置$ANDROID_HOME 在macOS上默认是~/Library/Android/sdk.

下面开始配置Rust开发环境

curl https://sh.rustup.sh -sSf | sh

rustup工具会自动的添加rust的工具到PATH中。

下面添加目标编译的工具链

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

下面开始配置NDK的开发环境。

mkdir ~/.NDK

$(ANDROID_HOME)/ndk-bundle/build/tools/make_standalone_toolchain.py --api 26 --arch arm64 --install-dir ~/.NDK/arm64;
$(ANDROID_HOME)/ndk-bundle/build/tools/make_standalone_toolchain.py --api 26 --arch arm --install-dir ~/.NDK/arm;
$(ANDROID_HOME)/ndk-bundle/build/tools/make_standalone_toolchain.py --api 26 --arch x86 --install-dir ~/.NDK/x86;

配置完之后我们将信息写入到 ~/.cargo/config

[target.aarch64-linux-android]
ar = ".NDK/arm64/bin/aarch64-linux-android-ar"
linker = ".NDK/arm64/bin/aarch64-linux-android-clang"

[target.armv7-linux-androideabi]
ar = ".NDK/arm/bin/arm-linux-androideabi-ar"
linker = ".NDK/arm/bin/arm-linux-androideabi-clang"

[target.i686-linux-android]
ar = ".NDK/x86/bin/i686-linux-android-ar"
linker = ".NDK/x86/bin/i686-linux-android-clang"

Hello World

配置完上述开发环境就可以开始编写代码了,这个例子我们来编写一个Hello World的程序用来验证。

首先创建项目

mkdir rust-android-example
cd rust-android-example

cargo new rust --lib
cd rust

Cargo.toml 代码

[dependencies]
jni = {version = "0.10.2", default-features = false}

[profile.release]
lto = true

[lib]
name="rust"
crate-type=["cdylib"]

lib.rs 代码

#![cfg(target_os="android")]
#![allow(non_snake_case)]

use std::ffi::{CString, CStr};
use jni::JNIEnv
use jni::objects::{JObject, JString};
use jin::sys::{jstring};

#[no_mangle]
pub unsafe extern fn Java_com_example_android_MainActivity_hello(env: JNIEnv, _: JObject, j_recipient: JString) -> jstring {
    let recipient = CString::from(
    	CStr::from_prt(env.get_string(j_recipient).unwrap().as_ptr())
    );
    let output = env.new_string("Hello ".to_owned() + recipient.to_str().unwrap()).unwrap();
    output.into_inner()
}

#[cfg(target_os="android")]表示只有在目标平台是Android的时候才开启,由于JNI要求驼峰命名,所以要开启#[allow(non_snake_case)]

现在就可以生成Android的lib了。

// cargo-build.sh
cargo build --target aarch64-linux-android --release
cargo build --target armv7-linux-androideabi --release
cargo build --target i686-linux-android --release

Android 开发

使用Android Studio 创建项目,公司domain写成example.com 需要和上面Rust中lib.rs 相同 ,项目名称叫android(后面需要复制脚本)

cd rust-android-example

mkdir android/app/src/main/jniLibs
mkdir android/app/src/main/jniLibs/arm64-v8a
mkdir android/app/src/main/jniLibs/armeabi-v7a
mkdir android/app/src/main/jniLibs/x86

cp rust/target/aarch64-linux-android/release/librust.so android/app/src/main/jniLibs/arm64-v8a/librust.so
cp rust/target/armv7-linux-androideabi/release/librust.so android/app/src/main/jniLibs/armeabi-v7a/librust.so
cp rust/target/i686-linux-android/release/librust.so android/app/src/main/jniLibs/x86/librust.so

将上面生成的target 复制到android目录下

MainActivity.java

public class MainActivity extends AppCompatActivity {

    // Used to load the 'native-lib' library on application startup.
    static {
        System.loadLibrary("rust");
    }
    public native String hello(String to);

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Example of a call to a native method
        TextView tv = (TextView) findViewById(R.id.sample_text);
        tv.setText(hello("android"));
    }
}

直接启动就可以看到 hello android显示在手机上了。