Normally, a Bevy application can be exit with AppExit, but on Android, that is not enough and can cause the app fails to reopen. To completely exit the Bevy application on Android, we need to do that from the Android side.
Start with the Android example: https://github.com/bevyengine/bevy/tree/main/examples/mobile/android_example
Java wrapper
In MainActivity.java
, add a function for exit the app, so Bevy app can call it in the Rust side:
...
import android.os.Handler;
public class MainActivity extends GameActivity {
...
// This function will exit the Android app
public void exitAppActivity() {
// `finishAffinity` needs to be run in main thread
new Handler().post(new Runnable() {
@Override
public void run() {
MainActivity.this.finishAffinity();
}
});
}
}
Bevy app
Add dependency to jni
for android target in Cargo.toml
.
[target.'cfg(target_os = "android")'.dependencies]
jni = "0.21"
In Bevy app, call the Android function above:
#[bevy_main]
fn main() {
let mut app = App::new();
...
app.run();
// Exit the Android app after Bevy job is finished
#[cfg(target_os = "android")]
exit_android_app();
}
#[cfg(target_os = "android")]
fn exit_android_app() -> anyhow::Result<()> {
let ctx = bevy::window::ANDROID_APP.get().expect("ANDROID_APP should be defined");
let vm = unsafe { jni::JavaVM::from_raw(ctx.vm_as_ptr() as *mut *const jni::sys::JNIInvokeInterface_) }?;
let activity = unsafe { jni::objects::JObject::from_raw(ctx.activity_as_ptr() as *mut jni::sys::_jobject) };
let mut env = vm.attach_current_thread()?;
// Call Android function
env.call_method(activity, "exitAppActivity", "()V", &[])?;
Ok(())
}