Hi! I've built my android APK with cargo apk
, but when I run it - it crahes. What did I do wrong?
Something.
If you want useful help, you'll have to provide useful information about the kind of error you got.
4 Likes
Did you compile for the correct cpu architecture? Does it crash with a specific error?
Sorry. My main.rs
is
#[cfg_attr(target_os = "android", ndk_glue::main(backtrace = "on"))]
fn main() {
enumerate_audio_devices().unwrap();
}
const GET_DEVICES_OUTPUTS: jni::sys::jint = 2;
fn enumerate_audio_devices() -> Result<(), Box<dyn std::error::Error>> {
// Create a VM for executing Java calls
let native_activity = ndk_glue::native_activity();
let vm_ptr = native_activity.vm();
let vm = unsafe { jni::JavaVM::from_raw(vm_ptr) }?;
let env = vm.attach_current_thread()?;
// Query the global Audio Service
let class_ctxt = env.find_class("android/content/Context")?;
let audio_service = env.get_static_field(class_ctxt, "AUDIO_SERVICE", "Ljava/lang/String;")?;
let audio_manager = env
.call_method(
native_activity.activity(),
"getSystemService",
// JNI type signature needs to be derived from the Java API
// (ArgTys)ResultTy
"(Ljava/lang/String;)Ljava/lang/Object;",
&[audio_service],
)?
.l()?;
// Enumerate output devices
let devices = env.call_method(
audio_manager,
"getDevices",
"(I)[Landroid/media/AudioDeviceInfo;",
&[GET_DEVICES_OUTPUTS.into()],
)?;
println!("-- Output Audio Devices --");
let device_array = devices.l()?.into_inner();
let len = env.get_array_length(device_array)?;
for i in 0..len {
let device = env.get_object_array_element(device_array, i)?;
// Collect device information
// See https://developer.android.com/reference/android/media/AudioDeviceInfo
let product_name: String = {
let name =
env.call_method(device, "getProductName", "()Ljava/lang/CharSequence;", &[])?;
let name = env.call_method(name.l()?, "toString", "()Ljava/lang/String;", &[])?;
env.get_string(name.l()?.into())?.into()
};
let id = env.call_method(device, "getId", "()I", &[])?.i()?;
let ty = env.call_method(device, "getType", "()I", &[])?.i()?;
let sample_rates = {
let sample_array = env
.call_method(device, "getSampleRates", "()[I", &[])?
.l()?
.into_inner();
let len = env.get_array_length(sample_array)?;
let mut sample_rates = vec![0; len as usize];
env.get_int_array_region(sample_array, 0, &mut sample_rates)?;
sample_rates
};
println!("Device {}: Id {}, Type {}", product_name, id, ty);
println!("sample rates: {:#?}", sample_rates);
}
Ok(())
}
cargo.toml
:
[package]
name = "android_test"
version = "0.1.0"
authors = ["..."]
edition = "2018"
crate-type = ["lib", "cdylib"]
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
[target.'cfg(target_os = "android")'.dependencies]
ndk-glue = { version="*" }
ndk = { version = "*", features = ["trace"] }
jni = "0.17"
[package.metadata.android]
apk_label = "Rust apk test"
target_sdk_version = 29
min_sdk_version = 26
I've built it with cargo apk
PS C:\Users\...\project\android_test> cargo apk build --release
Warning: You use environment variable ANDROID_HOME that is deprecated.Please, remove it and use ANDROID_SDK_ROOT instead. Now ANDROID_HOME is used
warning: unused manifest key: package.crate-type
Finished release [optimized] target(s) in 3.06s
Error: Path "C:\\Users\\...\\project\\android_test\\target\\aarch64-linux-android\\release\\libandroid_test.so" doesn't exist.
PS C:\Users\...\project\android_test>
crash
If you have the Android development tools installed, the adb logcat
command should show you more information about the crash.
Relevant log:
09-25 22:39:51.585 16911 16911 E AndroidRuntime: java.lang.RuntimeException: Unable to start activity ComponentInfo{rust.android_test/android.app.NativeActivity}: java.lang.IllegalArgumentException: Unable to find native library android_test using classloader: dalvik.system.PathClassLoader[DexPathList[[],nativeLibraryDirectories=[/data/app/rust.android_test-hiDUFecEbpAG8I_acWqtwA==/lib/arm64, /system/lib64]]]
09-25 22:39:51.585 16911 16911 E AndroidRuntime: at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3363)
09-25 22:39:51.585 16911 16911 E AndroidRuntime: at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3498)
09-25 22:39:51.585 16911 16911 E AndroidRuntime: at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
09-25 22:39:51.585 16911 16911 E AndroidRuntime: at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
09-25 22:39:51.585 16911 16911 E AndroidRuntime: at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
09-25 22:39:51.585 16911 16911 E AndroidRuntime: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2255)
09-25 22:39:51.585 16911 16911 E AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:106)
09-25 22:39:51.585 16911 16911 E AndroidRuntime: at android.os.Looper.loop(Looper.java:193)
09-25 22:39:51.585 16911 16911 E AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:7169)
09-25 22:39:51.585 16911 16911 E AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method)
09-25 22:39:51.585 16911 16911 E AndroidRuntime: at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
09-25 22:39:51.585 16911 16911 E AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:911)
09-25 22:39:51.585 16911 16911 E AndroidRuntime: Caused by: java.lang.IllegalArgumentException: Unable to find native library android_test using classloader: dalvik.system.PathClassLoader[DexPathList[[],nativeLibraryDirectories=[/data/app/rust.android_test-hiDUFecEbpAG8I_acWqtwA==/lib/arm64, /system/lib64]]]
09-25 22:39:51.585 16911 16911 E AndroidRuntime: at android.app.NativeActivity.onCreate(NativeActivity.java:161)
09-25 22:39:51.585 16911 16911 E AndroidRuntime: at android.app.Activity.performCreate(Activity.java:7193)
09-25 22:39:51.585 16911 16911 E AndroidRuntime: at android.app.Activity.performCreate(Activity.java:7184)
09-25 22:39:51.585 16911 16911 E AndroidRuntime: at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1271)
09-25 22:39:51.585 16911 16911 E AndroidRuntime: at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3343)
09-25 22:39:51.585 16911 16911 E AndroidRuntime: ... 11 more
09-25 22:39:51.589 1984 10335 W ActivityManager: Force finishing activity rust.android_test/android.app.NativeActivity
[package]
name = "android_test"
version = "0.1.0"
authors = ["..."]
edition = "2018"
crate-type = ["lib", "cdylib"]
warning: unused manifest key: package.crate-type
The crate-type
must be in a [lib]
section. Also main.rs
should be called lib.rs
I think.
5 Likes
This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.