fix(android): export android_main and gate desktop-only window config
Three changes to get the APK past the NativeActivity launch crash: 1. Export `android_main` — NativeActivity dlopen-s libsolitaire_app.so and calls `android_main` as its entry point. Without the symbol the app crashed immediately with UnsatisfiedLinkError. The function sets bevy::android::ANDROID_APP (required by WinitPlugin) then delegates to the existing `run()`. 2. Gate `resize_constraints` to non-Android — on Android max_width and max_height default to 0.0; Bevy's clamp panicked with min=800 > max=0. 3. Gate `apply_smart_default_window_size` to non-Android — the system calls `.clamp(800.0, logical_w)` which panics when the window surface reports zero dimensions during early Android lifecycle events. Window sizing is OS-controlled on Android so the system is irrelevant there. Verified: app boots on x86_64 Android 14 emulator (Pixel_7 AVD, SwiftShader Vulkan), runs for 2+ minutes without crashing. Desktop build: clippy clean, 1282 tests passing. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Generated
+3
@@ -0,0 +1,3 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
Generated
+9
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$" />
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
||||
Generated
+8
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="MarkdownSettings">
|
||||
<option name="previewPanelProviderInfo">
|
||||
<ProviderInfo name="Compose (experimental)" className="com.intellij.markdown.compose.preview.ComposePanelProvider" />
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
||||
Generated
+6
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectRootManager" version="2" project-jdk-name="26" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/out" />
|
||||
</component>
|
||||
</project>
|
||||
Generated
+8
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/Rusty_Solitaire.iml" filepath="$PROJECT_DIR$/.idea/Rusty_Solitaire.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
||||
Generated
+6
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
@@ -116,6 +116,9 @@ pub fn run() {
|
||||
// small enough that a few stray dropped frames from
|
||||
// disabling vsync are imperceptible.
|
||||
present_mode: PresentMode::AutoNoVsync,
|
||||
// Android windows always fill the screen; max_width/max_height
|
||||
// default to 0.0, which panics Bevy's clamp when min > max.
|
||||
#[cfg(not(target_os = "android"))]
|
||||
resize_constraints: bevy::window::WindowResizeConstraints {
|
||||
min_width: 800.0,
|
||||
min_height: 600.0,
|
||||
@@ -195,6 +198,8 @@ pub fn run() {
|
||||
// every fresh launch can flip `disable_smart_default_size` in
|
||||
// Settings to opt out. The flag is checked once at startup; a
|
||||
// mid-session change applies on the next launch.
|
||||
// Android windows are always full-screen; the OS controls sizing.
|
||||
#[cfg(not(target_os = "android"))]
|
||||
if !had_saved_geometry && !settings.disable_smart_default_size {
|
||||
app.add_systems(Update, apply_smart_default_window_size);
|
||||
}
|
||||
@@ -335,6 +340,20 @@ fn set_window_icon(
|
||||
*applied = true;
|
||||
}
|
||||
|
||||
/// Android entry point called by NativeActivity after dlopen-ing the `.so`.
|
||||
/// Sets the `AndroidApp` handle that Bevy's winit backend reads before
|
||||
/// constructing the event loop, then delegates to [`run`].
|
||||
///
|
||||
/// The `#[bevy_main]` proc-macro would generate the same code but only
|
||||
/// works on a function named `main`; our shared entry point is `run`, so
|
||||
/// we emit the equivalent expansion manually.
|
||||
#[cfg(target_os = "android")]
|
||||
#[unsafe(no_mangle)]
|
||||
fn android_main(android_app: bevy::android::android_activity::AndroidApp) {
|
||||
let _ = bevy::android::ANDROID_APP.set(android_app);
|
||||
run();
|
||||
}
|
||||
|
||||
/// Wraps the default panic hook with one that also appends a crash log
|
||||
/// to `<data_dir>/crash.log` (next to `settings.json`). The default hook
|
||||
/// still runs afterwards, so stderr output and debugger integration are
|
||||
|
||||
Reference in New Issue
Block a user