Skip to content

Guard WebViewActivity against MissingWebViewPackageException#2994

Open
jim-daf wants to merge 1 commit into
onflow:devfrom
jim-daf:fix/issue-1256-webview-package-missing
Open

Guard WebViewActivity against MissingWebViewPackageException#2994
jim-daf wants to merge 1 commit into
onflow:devfrom
jim-daf:fix/issue-1256-webview-package-missing

Conversation

@jim-daf
Copy link
Copy Markdown

@jim-daf jim-daf commented Apr 22, 2026

Closes #1256

What is happening

WebViewActivity.onCreate calls setContentView(R.layout.activity_webview) and then loadUrl on the inflated LilicoWebView. On a small but nonzero share of devices the system WebView package is missing, disabled, or partially updated, and inflating any view that depends on it throws android.util.AndroidRuntimeException: java.lang.RuntimeException: Cannot load WebView. Because onCreate lets the exception escape, the process crashes and the user sees a generic Android error dialog with no idea what to do about it.

The Firebase report linked in #1256 has this exact stack trace, with the failure originating from MissingWebViewPackageException inside the platform code.

What this PR does

It wraps the inflate and loadUrl calls in a small try/catch. When the WebView package is missing the activity logs the error, shows a localized toast pointing the user at the Play Store entry for Android System WebView, and finishes itself instead of crashing. The same handler also catches the broader Exception so future variants of the same problem do not slip through.

The new string webview_unavailable is added to values/strings.xml only. Translators can pick it up later through the normal localization flow.

When the Android System WebView package is missing, disabled, or being updated, inflating the WebView throws an AndroidRuntimeException wrapping WebViewFactory.MissingWebViewPackageException. The activity then dies with no useful feedback for the user.

Wrap the inflation and initial load in try/catch, log the failure, show a localized message and finish gracefully so the user can recover by reinstalling or enabling Android System WebView.
@jim-daf jim-daf marked this pull request as ready for review April 22, 2026 20:13
@jim-daf jim-daf requested a review from a team as a code owner April 22, 2026 20:13
Copilot AI review requested due to automatic review settings April 22, 2026 20:13
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR hardens WebViewActivity against crashes caused by devices missing/disabled Android System WebView (reported in #1256) by handling the failure gracefully instead of letting onCreate crash the process.

Changes:

  • Wrap setContentView(activity_webview) + LilicoWebView.loadUrl(...) in a try/catch and finish the activity after showing an error toast.
  • Add a new user-facing string (webview_unavailable) for the toast message.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
app/src/main/java/com/flowfoundation/wallet/page/common/WebViewActivity.kt Adds exception handling around WebView inflation/loading, logs, toasts, and finishes instead of crashing.
app/src/main/res/values/strings.xml Adds the localized message shown when WebView is unavailable.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +26 to +38
try {
setContentView(R.layout.activity_webview)
findViewById<LilicoWebView>(R.id.webview).apply {
loadUrl(this@WebViewActivity.url!!)
}
} catch (e: AndroidRuntimeException) {
loge(e)
toast(R.string.webview_unavailable, Toast.LENGTH_LONG)
finish()
} catch (e: Exception) {
loge(e)
toast(R.string.webview_unavailable, Toast.LENGTH_LONG)
finish()
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new broad catch (e: Exception) will also catch unrelated failures (e.g., url!! NPE if the intent extra is missing after process death / external launch) and then shows webview_unavailable, which would be misleading and make debugging harder. Consider validating url before entering the WebView inflate/load block (and handling a missing URL separately), and limit the webview_unavailable toast to the specific WebView-provider failure (e.g., only for the known WebView inflation exception), while letting unexpected exceptions surface or showing a generic error.

Copilot uses AI. Check for mistakes.
Comment on lines +31 to +38
} catch (e: AndroidRuntimeException) {
loge(e)
toast(R.string.webview_unavailable, Toast.LENGTH_LONG)
finish()
} catch (e: Exception) {
loge(e)
toast(R.string.webview_unavailable, Toast.LENGTH_LONG)
finish()
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both catch blocks have identical handling. If the intent is just to guard WebView inflation, this can be simplified (single catch + type/cause check, or a small helper) to avoid duplication and reduce the chance the handlers diverge later.

Copilot uses AI. Check for mistakes.
Comment on lines +33 to +37
toast(R.string.webview_unavailable, Toast.LENGTH_LONG)
finish()
} catch (e: Exception) {
loge(e)
toast(R.string.webview_unavailable, Toast.LENGTH_LONG)
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

toast(R.string.webview_unavailable, Toast.LENGTH_LONG) does not match the toast(msgRes: Int = 0, msg: String? = null, duration: Int = ...) helper signature (the second positional parameter is msg: String?). This should be passed as a named argument (duration = Toast.LENGTH_LONG) or by providing msg = null explicitly; otherwise this will not compile.

Suggested change
toast(R.string.webview_unavailable, Toast.LENGTH_LONG)
finish()
} catch (e: Exception) {
loge(e)
toast(R.string.webview_unavailable, Toast.LENGTH_LONG)
toast(R.string.webview_unavailable, duration = Toast.LENGTH_LONG)
finish()
} catch (e: Exception) {
loge(e)
toast(R.string.webview_unavailable, duration = Toast.LENGTH_LONG)

Copilot uses AI. Check for mistakes.
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 this pull request may close these issues.

android.util.AndroidRuntimeException: android.util.AndroidRuntimeException:...

2 participants