Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Call ANativeActivity_finish() or GameActivity_finish() when android_main returns #67

Closed
rib opened this issue Mar 16, 2023 · 3 comments · Fixed by #81
Closed

Call ANativeActivity_finish() or GameActivity_finish() when android_main returns #67

rib opened this issue Mar 16, 2023 · 3 comments · Fixed by #81

Comments

@rib
Copy link
Collaborator

rib commented Mar 16, 2023

Additionally, expose an AndroidApp::finish() API that can be used to explicitly call the Activity::finish() method which will lead to the activity being stopped and destroyed (with a corresponding Destroy event)

@MarijnS95
Copy link
Member

MarijnS95 commented Mar 16, 2023

We weren't really sure how to deal with this in ndk-glue (rust-mobile/ndk#154, rust-mobile/ndk#160) because users may be spawning their own thread to create a looper in while blindly returning from android_main() (and everything would keep running iirc).

Perhaps this is different for android-activity, but the backstory may be relevant.

@rib
Copy link
Collaborator Author

rib commented Mar 16, 2023

Thanks, I vaguely recall reading those issues at some point but good to join the dots for the extra context.

I'm fairly sure that poll_events is documented to only be allowed from the "main" thread, which would be the thread that's spawned for android_main(). At the very least the design would break down if poll_events calls moved between threads and so there would always have to be some notion of a main thread.

android_main does several things that are thread-specific (ref:

//! # Main Thread Initialization
//!
//! Before `android_main()` is called, the following application state
//! is also initialized:
//!
//! 1. An I/O thread is spawned that will handle redirecting standard input
//! and output to the Android log, visible via `logcat`.
//! 2. A `JavaVM` and `Activity` instance will be associated with the [`ndk_context`] crate
//! so that other, independent, Rust crates are able to find a JavaVM
//! for making JNI calls.
//! 3. The `JavaVM` will be attached to the native thread
//! 4. A [Looper] is attached to the Rust native thread.
) , such as ensuring there's a Looper attached, and attaching JNI and it's a key part of the design that android_main gets run in its own thread.

If some application didn't want to run its looper within that android_main thread that would probably be a sign that they shouldn't be using android-activity, though theoretically it could be possible to support spawning another thread for running the looper so long as polling didn't move between threads.

Just double checking this, I see that the poll_events documentation currently says the API may panic if called from any thread besides the android_main - so any support for polling on another thread would be an API addition to relax that constraint:

/// # Panics
///
/// This must only be called from your `android_main()` thread and it may panic if called
/// from another thread.

@MarijnS95
Copy link
Member

(Edited your message to include the full referenced doc-comment lines in-line 🙂)

Indeed, we may have been wrong in assuming for and allowing the thread-spawn. Good to have the back-link to check our ideas, but at this point I'd say to go for it and call finish() after returning (and document this in the changelog), and see if anyone gets broken by it which seems unlikely given the above rules :)

rib added a commit to rib/android-activity that referenced this issue Apr 27, 2023
Calling Activity.finish() is what ensures the Activity will get
gracefully destroyed, including calling the Activity's onDestroy
method.

Fixes: rust-mobile#67
rib added a commit to rib/android-activity that referenced this issue Apr 27, 2023
Calling Activity.finish() is what ensures the Activity will get
gracefully destroyed, including calling the Activity's onDestroy
method.

Fixes: rust-mobile#67
rib added a commit that referenced this issue May 24, 2023
Calling Activity.finish() is what ensures the Activity will get
gracefully destroyed, including calling the Activity's onDestroy
method.

Fixes: #67
@rib rib closed this as completed in #81 Jun 19, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants