在 fragment 中 的webview 有的手机里 会闪退 报错信息如下:
image.png
chrome build fingerprint
rise I/Choreographer: Skipped 40 frames! The application may be doing too much work on its main thread.
This exception happens in the native code, there isn't much you can do in your Java code about it. Seems to be a graphic memory exhaustion, as it is crashing in malloc called from the GL library code. You say that the WebView is never destroyed, perhaps this is a result of memory fragmentation (the graphics code allocates / frees memory, and finally the memory map becomes so fragmented, that it's not possible to find a contiguous block of the requested size). I would suggest considering destroying and recreating WebView from time to time.
这种异常发生在本机代码中,在Java代码中对此无能为力。似乎是图形内存耗尽,因为它在从GL库代码调用的malloc中崩溃。您说WebView永远不会被破坏,这可能是内存碎片的结果(图形代码分配/释放内存,最后内存映射变得如此碎片化,以至于不可能找到具有请求大小的连续块)。我建议不时地考虑销毁和重新创建WebView。
Because Chrome usually runs GPU-related code in a separate process. So when it crashes, the main Chrome app process is not affected and continues to run. But in WebView everything is within a single app process, so crash in one component brings down the whole app.
因为Chrome通常在一个单独的进程中运行与gpu相关的代码。因此,当它崩溃时,主Chrome应用程序进程不受影响,并继续运行。但在WebView中,所有东西都在一个应用程序进程中,因此在一个组件中崩溃会导致整个应用程序崩溃。
image.png
内存占用 在大的 h5页面 增加比较多
web内存优化
1.获取系统分配的最大内存
...
android:largeHeap="true"
...>
...
获取手机分配的内存 查看/system/build.prop文件内容:
image.png
对于本人这台手机,系统正常分配的内存最多为192M;当设置largeHeap时,最多可申请512M。当超过这个值时,就会出现OOM了
2.独立的web进程,与主进程隔开
这个方法被运用于类似qq,微信这样的超级app中,这也是解决任何webview内存问题屡试不爽的方法
对于封装的webactivity,在manifest.xml中设置
android:name=".webview.WebViewActivity"
android:launchMode="singleTop"
android:process=":remote"
android:screenOrientation="unspecified" />
然后在关闭webactivity时销毁进程
@Overrideprotected
void onDestroy() {
super.onDestroy();
System.exit(0);}
关闭浏览器后便销毁整个进程,这样一般95%的情况下不会造成内存泄漏之类的问题,但这就涉及到android进程间通讯,比较不方便处理, 优劣参半,也是可选的一个方案.
这个方案 测试里以后 确实不会再闪退
3.将webview的创建放在activity中用new WebView(getApplicationContext())的方式,并且修改webview的销毁为
@Override
protected void onDestroy() {
if( mWebView!=null) {
// 如果先调用destroy()方法,则会命中if (isDestroyed()) return;这一行代码,需要先onDetachedFromWindow(),再
// destory()
ViewParent parent = mWebView.getParent();
if (parent != null) {
((ViewGroup) parent).removeView(mWebView);
}
mWebView.stopLoading();
// 退出时调用此方法,移除绑定的服务,否则某些特定系统会报错
mWebView.getSettings().setJavaScriptEnabled(false);
mWebView.clearHistory();
mWebView.clearView();
mWebView.removeAllViews();
mWebView.destroy();
}
super.on Destroy();
4. 从根源解决(划重点)