-
-
Notifications
You must be signed in to change notification settings - Fork 965
fix(WebView): properly recover when the renderer process is gone (refs #5823) #6793
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -581,12 +581,32 @@ class WebViewActivity : | |
| } | ||
|
|
||
| override fun onRenderProcessGone(view: WebView?, handler: RenderProcessGoneDetail?): Boolean { | ||
| Timber.e("onRenderProcessGone: webView crashed") | ||
| view?.let { | ||
| reload() | ||
| lifecycleScope.launch { | ||
| webViewAddJavascriptInterface() | ||
| val didCrash = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { | ||
| handler?.didCrash() == true | ||
| } else { | ||
| // On API < 26 didCrash() is unavailable; treat as a crash so we still recover. | ||
| true | ||
| } | ||
| Timber.e( | ||
| "onRenderProcessGone: WebView renderer is gone (didCrash=$didCrash). " + | ||
| "This is commonly triggered by a GPU context loss or out-of-memory in the " + | ||
| "renderer process (see #5823 — Mali GPU + EXT_robustness on Android 10), " + | ||
| "which can leave dashboard cards rendering as blank/greyed-out surfaces. " + | ||
| "Recreating the activity to recover with a fresh WebView.", | ||
| ) | ||
| // Per the android.webkit.WebView contract, once the render process is gone the | ||
| // WebView instance is unusable and must not be touched again — calling reload() | ||
| // on the dead WebView is a no-op and leaves the user looking at greyed-out | ||
| // cards forever. Detach and destroy the dead WebView so its native resources | ||
| // are released, then recreate the activity to rebuild a fresh WebView and | ||
| // reload the last URL through the normal onCreate path. Returning `true` tells | ||
| // the system we have handled the crash so the hosting app process is not killed. | ||
| if (!isFinishing && !isRelaunching) { | ||
| view?.let { dead -> | ||
| (dead.parent as? android.view.ViewGroup)?.removeView(dead) | ||
| dead.destroy() | ||
| } | ||
| recreate() | ||
| } | ||
|
Comment on lines
+604
to
610
|
||
|
|
||
| return true | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The API < 26 branch/comment is misleading: framework
WebViewClient.onRenderProcessGone(...)is only invoked on API ≥ 26, so this branch won’t run in practice. Consider simplifying toval didCrash = handler?.didCrash() == trueand updating the comment accordingly (or rewording it as a defensive fallback for unexpected/null detail rather than an API-level behavior).