Coder Agent: Fix an Android SDK bug where tapping the chat text input field causes the chat UI to crash into a lo#23
Conversation
… field causes the chat UI to crash into a loading state with a blank pink/magenta screen. After a recent SDK update, users on Android (specific
There was a problem hiding this comment.
Pull request overview
This PR aims to prevent the Gleap Android chat UI (WebView-based) from resetting into a blank loading state when the soft keyboard opens / input is focused, by avoiding Activity recreation on certain configuration changes and improving WebView state restoration.
Changes:
- Adjusted soft keyboard handling behavior and added an explicit
onConfigurationChangedoverride to avoid Activity recreation. - Refactored WebView initialization to separate “settings/clients/bridge setup” from “URL load” and altered the saved-state restore flow.
- Expanded
android:configChangesforGleapMainActivityto keep the WebView alive across more configuration changes.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
gleap/src/main/java/io/gleap/GleapMainActivity.java |
Refactors WebView init/restore and adds configuration-change handling to prevent chat state loss when keyboard opens. |
gleap/src/main/AndroidManifest.xml |
Expands configChanges so the Activity won’t be recreated on more configuration changes. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if (restored == null) { | ||
| // restoreState failed — fall back to a full reload. | ||
| webView.loadUrl(url); |
There was a problem hiding this comment.
In the savedInstanceState != null path you call initBrowserSettings() (which sets the WebView INVISIBLE) and then webView.restoreState(...), but if restoreState succeeds there is no native code path that hides R.id.loader / shows the WebView (the only hide/show is triggered by the JS "ping" message). If the restored page does not re-emit that ping, the UI can remain stuck in an infinite loader/blank state after process recreation. Consider explicitly showing the WebView / hiding the loader after a successful restore, or triggering a reload/timeout fallback when the ping isn’t received.
| if (restored == null) { | |
| // restoreState failed — fall back to a full reload. | |
| webView.loadUrl(url); | |
| if (restored == null || restored.getSize() == 0) { | |
| // restoreState failed — fall back to a full reload. | |
| webView.loadUrl(url); | |
| } else { | |
| // Successfully restored a previous page. Ensure that the | |
| // WebView is visible and the loader is hidden, since the | |
| // restored content might not re-emit the JS "ping". | |
| webView.setVisibility(View.VISIBLE); | |
| View loader = findViewById(R.id.loader); | |
| if (loader != null) { | |
| loader.setVisibility(View.GONE); | |
| } |
| @@ -308,6 +324,15 @@ protected void onRestoreInstanceState(Bundle savedInstanceState) { | |||
| webView.restoreState(savedInstanceState); | |||
There was a problem hiding this comment.
webView.restoreState(savedInstanceState) is invoked in the webView.post(...) runnable (saved-state branch) and again in onRestoreInstanceState(). Restoring twice can lead to redundant work and can overwrite state after clients/settings have been attached, making behavior harder to reason about. Consider choosing a single restore location (either rely on onRestoreInstanceState or gate the second call with a flag).
| webView.restoreState(savedInstanceState); | |
| // WebView state is restored in onCreate via the savedInstanceState branch. |
| <activity | ||
| android:name="io.gleap.GleapMainActivity" | ||
| android:configChanges="orientation|screenSize" | ||
| android:configChanges="orientation|screenSize|keyboard|keyboardHidden|screenLayout|smallestScreenSize|uiMode|navigation|density" |
There was a problem hiding this comment.
The activity now claims to handle a very broad set of configChanges (including density and uiMode). When these are listed, Android will not recreate the Activity and will also not automatically re-apply updated resources for those configuration changes, which can cause incorrect theming/scaling after dark-mode changes or display-size/density changes. Consider narrowing this list to only the minimum needed to prevent the keyboard-related recreation (and leave other changes to the default recreation behavior).
| android:configChanges="orientation|screenSize|keyboard|keyboardHidden|screenLayout|smallestScreenSize|uiMode|navigation|density" | |
| android:configChanges="orientation|screenSize|keyboard|keyboardHidden" |
… infinite loading spinner when the keyboard opens after tapping the text input field. After a recent SDK update, on a Samsung Galaxy S22 Ultra
Automated changes by Gleap Coder Agent.
Task: Fix an Android SDK bug where tapping the chat text input field causes the chat UI to crash into a loading state with a blank pink/magenta screen.
After a recent SDK update, users on Android (specifically observed on Samsung Galaxy S22 Ultra running Android 16 / One UI 8.0) experience a critical UI bug in the chat widget: when tapping the text input field to type a reply, the entire chat history disappears and is replaced by an infinite loading spinner on a blank pink/magenta background, rendering the chat completely unusable.
Requirements
Context
BP2A.250605.031.A3.S908EXXSCGYK2Visual Evidence
The screen recording clearly shows the following sequence:
This strongly suggests that the keyboard open/input focus event is triggering a re-render, data refetch, or component reinitialization that fails to complete.
Key Insights from Discussion
Implementation Notes
onConfigurationChanged,adjustResize/adjustPanwindow soft input mode handling, or anyViewTreeObserverlayout listeners that might be triggering unintended behaviortruebut never resolved. Check for race conditions or failed promises/callbacks in the chat message loading flowWindowInsetsCompathandling — Android 16 may have changes to how keyboard insets are reported, which could break existing layout adjustment logic