Làm thế nào để hoàn toàn thoát Bevy app trên Android

Thông thường, chúng ta có thể dừng và thoát một chương trình Bevy với sự kiện AppExit. Nhưng trên Android, app sẽ không được thoát hoàn toàn và bị lỗi không thể mở lại được. Để hoàn toàn thoát chương trình Bevy trên Android, chúng ta cần phải đóng ứng dụng từ phía Android.

Ví dụ để gọi Bevy app trên Android có thể tham khảo ở đây: https://github.com/bevyengine/bevy/tree/main/examples/mobile/android_example

Java wrapper

Trong MainActivity trong MainActivity.java, tạo một hàm để đóng app. Hàm này sẽ được gọi từ phía Rust code:

...
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

Trong file Cargo.toml, thêm dependency cho target android:

[target.'cfg(target_os = "android")'.dependencies]
jni = "0.21"

Trong Bevy app, gọi hàm Android đã được định nghĩa ở phía trên:

#[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(())
}

Bài liên quan

comments powered by Disqus