下面我发布了我当前的onRenderProcessGone。
- 在
if (!detail.didCrash()) {}
中,实例变量“view”保证为 null,因此可以安全地重新初始化它。我应该自己重新初始化它还是系统会这样做? 您能否指定应用程序如何继续执行的逻辑示例?如何更优雅地处理崩溃?
@TargetApi(Build.VERSION_CODES.O) @Override public boolean onRenderProcessGone(WebView view, RenderProcessGoneDetail detail) { // WebViewClient.onRenderProcessGone was added in O. if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) { return false; } super.onRenderProcessGone(view, detail); if (!detail.didCrash()) { // Renderer was 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", "System killed the WebView rendering process " + "to reclaim memory. Recreating..."); if (view != null) { ((ViewGroup)view.getParent()).removeView(view); view.destroy(); view = null; } // By this point, the instance variable "view" is guaranteed // to be null, so it's safe to reinitialize it. return true; // The app continues executing. } // Renderer crashed because of an internal error, such as a memory // access violation. Log.e("MY_APP", "The WebView rendering process crashed!"); // In this example, the app itself crashes after detecting that the // renderer crashed. If you choose to handle the crash more gracefully // and allow your app to continue executing, you should 1) destroy the // current WebView instance, 2) specify logic for how the app can // continue executing, and 3) return "true" instead. return false; }
最佳答案
我已经实现了这个方法,并且没有区分渲染器崩溃或被系统杀死。就应用程序而言,结果是相同的 - webview 无法使用,如果此方法返回 false,应用程序也会被终止。
我在 fragment/Activity 创建期间初始化的 fragment (或 Activity )中维护对 WebView 的引用和两个布局 Root View 。
m_homeWebSwipe = v.findViewById(R.id.homeWebViewSwipe);
m_homeWebView = v.findViewById(R.id.homeWebView);
initializeWebView(m_homeWebView);
我的 WebView 是 SwipeRefreshLayout 的子级。布局 XML 并不重要,但作为引用,它是:
<?xml version="1.0" encoding="utf-8"?>
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/homeWebViewSwipe"
android:layout_width="match_parent"
android:layout_height="match_parent">
<WebView
android:id="@+id/homeWebView"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</WebView>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
这里的关键是 WebView 包含在 View 根部的布局容器中。
收到 onRenderProcessGone
事件后,目标是重新创建一个包含新 WebView 的功能 View (它将有一个与之关联的新渲染器进程)。
@Override
public boolean onRenderProcessGone(final WebView view, RenderProcessGoneDetail detail) {
// Renderer was killed or died, recreate the webview
Log.e("HomeWebView", "web content rendering process killed - resetting WebView: " + view.hashCode());
// Only handle our WebView
if (m_homeWebView.equals(view)) {
// Get the parent container of the inflated layout
ViewGroup container = (ViewGroup) m_homeWebSwipe.getParent();
ViewGroup.LayoutParams params = container.getLayoutParams();
// Remove the inflated view from the container and cleanup
// the dead webview specifically (if it is not GC'ed it will cause
// problems later, the next time the renderer dies)
container.removeView(m_homeWebSwipe);
m_homeWebSwipe = null;
m_homeWebView = null;
view.destroy();
// Reinflate the view layout and add it back into the container
View v = getLayoutInflater().inflate(R.layout.home_webview_screen, container, false);
m_homeWebSwipe = v.findViewById(R.id.homeWebViewSwipe);
m_homeWebView = v.findViewById(R.id.homeWebView);
// Initialise webview here, same as when it was originally created
initializeWebView(m_homeWebView);
assert(getActivity() != null);
getActivity().setContentView(v, params);
// reload the displayed page, or load a new page here
reloadPage();
return true; // The app continues executing.
}
return false; // the app is killed
}
您可以通过安排 WebView 加载 URL chrome://crash 来测试 onRenderProcessGone
方法中的代码
关于android - onRenderProcessGone(WebView View , RenderProcessGoneDetail 详细信息) 示例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46737984/