Reputation: 51
I have an Android app with a webview that crashes after about 15 minutes of running. There isn't a stacktrace on logcat, only the following error message appears before the crash :
[ERROR:aw_browser_terminator.cc(81)] Render process (29413) kill (OOM or update) wasn't handed by all associated webviews, killing application.
What could be the cause of this?
NB : The webview loads an Angular 5 web application which contains a few svg charts.
Edit
My code is the following
final WebSettings ws = webView.getSettings();
ws.setJavaScriptEnabled(true);
ws.setDomStorageEnabled(true);
ws.setAllowContentAccess(true);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
ws.setAllowFileAccessFromFileURLs(true);
ws.setAllowUniversalAccessFromFileURLs(true);
}
webView.setWebViewClient(new WebViewClient());
webView.setWebChromeClient(new WebChromeClient());
webView.loadUrl("http://192.168.137.133/sectiontasks");
Upvotes: 3
Views: 3000
Reputation: 125
Very useful for those to handle webview crash and recover from it.
Termination Handling API The Termination Handling API handles cases where the renderer process for a WebView object goes away, either because the system kills the renderer to reclaim necessary memory or because the renderer process crashes. By using this API, you let your app continue executing, even though the renderer process goes away.
https://developer.android.com/develop/ui/views/layout/webapps/managing-webview#termination-handle
public class MyRendererTrackingWebViewClient extends WebViewClient {
private WebView mWebView;
@Override
public boolean onRenderProcessGone(WebView view,
RenderProcessGoneDetail detail) {
if (!detail.didCrash()) {
// Renderer is killed because the system ran out of memory. The app
// can recover gracefully by creating a new WebView instance in the
// foreground.
Log.e("MY_APP_TAG", "System killed the WebView rendering process " +
"to reclaim memory. Recreating...");
if (mWebView != null) {
ViewGroup webViewContainer =
(ViewGroup) findViewById(R.id.my_web_view_container);
webViewContainer.removeView(mWebView);
mWebView.destroy();
mWebView = null;
}
// By this point, the instance variable "mWebView" is guaranteed to
// be null, so it's safe to reinitialize it.
return true; // The app continues executing.
}
// Renderer crashes because of an internal error, such as a memory
// access violation.
Log.e("MY_APP_TAG", "The WebView rendering process crashed!");
// In this example, the app itself crashes after detecting that the
// renderer crashed. If you handle the crash more gracefully and let
// your app continues executing, you must destroy the current WebView
// instance, specify logic for how the app continues executing, and
// return "true" instead.
return false;
}
}
Destroying webview
private void destroyWebview() {
if (webView != null) {
Utilities.logThis("MainActivity destroyWebview DESTROY WebView ... ACTION");
//ViewGroup webViewContainer = (ViewGroup) findViewById(R.id.webview_container);
webviewContainer.removeView(webView);
webView.stopLoading(); // Stop any ongoing loading in case of a crash
webView.onPause(); // Pause JavaScript execution
webView.clearHistory(); // Clear WebView history
webView.clearFormData();
webView.removeAllViews(); // Remove all child views
webView.clearCache(true);
webView.destroy(); // Destroy the WebView
webView = null; // Set the WebView reference to null
webViewClient = null;
}
}
Reconstruction it programmatically
public void setupWebview() {
//webView = (WebView) findViewById(R.id.webview);
// Create a new WebView instance
webView = new WebView(this);
webView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
// Add the WebView to the container
webviewContainer.addView(webView);
Log.d("setupWebview", "Webview created " + webView);
//Enabling hardware acceleration for WebView can improve performance but may also lead to crashes. You can disable it if it's causing issues:
webView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setDomStorageEnabled(true);
webView.getSettings().setLoadsImagesAutomatically(true);
webView.getSettings().setAllowContentAccess(true);
webView.getSettings().setLoadWithOverviewMode(true);
//webView.getSettings().setAppCacheEnabled(true);
//webView.getSettings().setAppCacheMaxSize(1024 * 1024 * 8); // 8MB
webView.getSettings().setUseWideViewPort(true);
webView.getSettings().setMediaPlaybackRequiresUserGesture(false);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
webView.getSettings().setSafeBrowsingEnabled(false);
}
webView.getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
//webView.setWebViewClient(new WebViewClient()); //https://stackoverflow.com/questions/48054518/android-app-not-connecting-to-internet-on-emulator
webView.setRendererPriorityPolicy(WebView.RENDERER_PRIORITY_BOUND, true);
//webViewClient = new MyRendererTrackingWebViewClient(this, webView);
webViewClient = new MyWebViewClient();
webView.setWebViewClient(webViewClient);
CookieManager cookieManager = CookieManager.getInstance();
cookieManager.setAcceptCookie(false);
cookieManager.setAcceptThirdPartyCookies( webView, false);
}
Upvotes: 0