1. Project Structure
Organize your project to manage both PC and Android builds:
bash
코드 복사
my_rust_jni_project/
├── src/
│ └── lib.rs # Shared Rust logic for both PC and Android
├── Cargo.toml # Rust configuration
├── build_scripts/
│ └── build_android.sh # Android build script
│ └── build_pc.bat # PC build script
└── target/ # Output directory for builds
2. Write Shared Rust Code
Create a single Rust library with shared logic for both platforms. Use cfg attributes to include platform-specific code.
src/lib.rs:
Code: Select all
use jni::JNIEnv;
use jni::objects::JClass;
use jni::sys::jstring;
#[no_mangle]
#[cfg(target_os = "android")]
pub extern "system" fn Java_com_example_android_HelloJni_helloRust(
env: JNIEnv,
_class: JClass,
) -> jstring {
let output = env.new_string("Hello from Rust on Android!").expect("Couldn't create Java string");
output.into_inner()
}
#[no_mangle]
#[cfg(not(target_os = "android"))] // For PC
pub extern "system" fn Java_com_example_pc_HelloJni_helloRust(
env: JNIEnv,
_class: JClass,
) -> jstring {
let output = env.new_string("Hello from Rust on PC!").expect("Couldn't create Java string");
output.into_inner()
}
To set up a build environment that can handle both PC JNI and Android JNI simultaneously, you can leverage Rust's cross-compilation features and Cargo's flexibility. Here's how you can organize your project:
1. Project Structure
Organize your project to manage both PC and Android builds:
Code: Select all
my_rust_jni_project/
├── src/
│ └── lib.rs # Shared Rust logic for both PC and Android
├── Cargo.toml # Rust configuration
├── build_scripts/
│ └── build_android.sh # Android build script
│ └── build_pc.bat # PC build script
└── target/ # Output directory for builds
Create a single Rust library with shared logic for both platforms. Use cfg attributes to include platform-specific code.
src/lib.rs:
Code: Select all
use jni::JNIEnv;
use jni::objects::JClass;
use jni::sys::jstring;
#[no_mangle]
#[cfg(target_os = "android")]
pub extern "system" fn Java_com_example_android_HelloJni_helloRust(
env: JNIEnv,
_class: JClass,
) -> jstring {
let output = env.new_string("Hello from Rust on Android!").expect("Couldn't create Java string");
output.into_inner()
}
#[no_mangle]
#[cfg(not(target_os = "android"))] // For PC
pub extern "system" fn Java_com_example_pc_HelloJni_helloRust(
env: JNIEnv,
_class: JClass,
) -> jstring {
let output = env.new_string("Hello from Rust on PC!").expect("Couldn't create Java string");
output.into_inner()
}
Update Cargo.toml to handle builds for both PC and Android:
Code: Select all
[lib]
crate-type = ["cdylib"]
[dependencies]
jni = "0.21"
[profile.release]
panic = "abort"
For PC builds (Windows, Linux, macOS), use the native Rust toolchain.
Windows Example:
Add build_pc.bat
Code: Select all
cargo build --release
Cross-Platform Example:
You can build for all platforms from a single host using Cargo:
Linux:
Code: Select all
cargo build --release --target x86_64-unknown-linux-gnu
Code: Select all
cargo build --release --target x86_64-apple-darwin
Use cargo-ndk to streamline Android builds.
Install cargo-ndk:
Code: Select all
cargo install cargo-ndk
Code: Select all
#!/bin/bash
# Build for ARM64 (most common Android ABI)
cargo ndk -t arm64-v8a -o ./android_libs build --release
# Build for other ABIs (optional)
# cargo ndk -t armeabi-v7a -o ./android_libs build --release
# cargo ndk -t x86_64 -o ./android_libs build --release
Code: Select all
bash build_scripts/build_android.sh
6. Integrate Both Builds
For PC (Java Desktop):
Place the .dll (Windows), .so (Linux), or .dylib (macOS) in the Java project's library path.
Use System.loadLibrary("rust_library_name") in Java.
For Android:
Place the .so files in the appropriate jniLibs/<ABI>/ directories in your Android project.
Code: Select all
android {
sourceSets {
main {
jniLibs.srcDirs = ['src/main/jniLibs']
}
}
}
build_all.sh (Linux/macOS) or build_all.bat (Windows):
Code: Select all
#!/bin/bash
echo "Building for PC..."
cargo build --release
echo "Building for Android..."
bash build_scripts/build_android.sh
Code: Select all
bash build_all.sh