Fix Android crash-loop when native events dispatch before WebView is ready#130
Draft
simonhamp wants to merge 1 commit into
Draft
Fix Android crash-loop when native events dispatch before WebView is ready#130simonhamp wants to merge 1 commit into
simonhamp wants to merge 1 commit into
Conversation
…ready Queue plugin event dispatches until the WebView has finished loading a NativePHP page, use an absolute URL for the events fetch, and guard the MainActivity JS injection against a null document.body. Together these prevent the cold-boot crash-loop seen after the system kills the app (e.g. when a plugin opens system Settings during a permission flow). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
A customer report (geolocation plugin,
permanently_deniedbranch) surfaced a crash-loop on Android. The plugin's auto-open-Settings call lets Android kill the app process; on cold boot the geolocation coordinator dispatches aPermissionRequestResultevent before the WebView has loaded a NativePHP page. Three things then combine:NativeActionCoordinator.dispatchfetched a relative URL (/_native/api/events). Againstabout:blankit fails to parse, loggingFailed to parse URL from /_native/api/events.MainActivity.injectJavaScriptrandocument.body.classList.add(...)synchronously afterwebView.loadUrl(...). Against the cleared documentdocument.bodyisnull→Uncaught TypeError: Cannot read properties of null (reading 'classList')→ WebView dies → app crashes → cold boot → same race → loop.Changes
NativeActionCoordinator.kt— Added a process-wide readiness flag and event queue on the companion object.dispatch()now queues when the WebView isn't ready, uses the absolutehttp://127.0.0.1/_native/api/events, and wraps the JS body intry/catchso a broken page state can't throw an uncaught error. NewmarkWebViewReady(activity)/markWebViewNotReady()entry points.WebViewManager.kt—onPageFinishedcallsNativeActionCoordinator.markWebViewReady(...)for127.0.0.1URLs, flushing queued events.MainActivity.kt—onCreatecallsmarkWebViewNotReady()so cold boots inherit a clean gate.injectJavaScriptnow checksdocument.bodyand re-runs onDOMContentLoadedif the body isn't there yet, eliminating the classList crash.iOS is intentionally untouched:
LaravelBridge.shared.sendis only assigned after WebView setup, so it already has implicit gating against the same race.What this doesn't fix
The geolocation plugin's
permanently_deniedbranch still auto-opens the system Settings activity — that's still the trigger for the process kill, and lives innativephp/mobile-geolocation. With these changes the cold boot it provokes no longer crash-loops the app, but making that auto-open opt-in remains a reasonable UX change for the plugin.Test plan
Geolocation::requestPermissions(), deny twice to triggerpermanently_denied, return from Settings, confirm the app does not crash-loop.native-eventand the_native/api/eventsPOST lands (e.g. an alert button press still reaches Laravel).⏳ WebView not ready — queueing eventfollowed by▶️ Replaying N queued event(s)on cold boot when a plugin dispatches early.🤖 Generated with Claude Code