Android Webview 性能优化
2018-04-23 11:27
513 查看
1、内存泄漏解决方法
复写Webview,实现如下方法public MyWebView(Context context, AttributeSet attrs) { super(context, attrs, android.R.attr.webViewStyle); setBackgroundColor(Color.TRANSPARENT); // 删除掉Android默认注册的JS接口 removeDefaultJavascriptInterface(); WindowManager wm= (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE); setConfigCallback(wm); } @Override public void destroy() { getSettings().setJavaScriptEnabled(false); this.clearFormData(); this.clearHistory(); this.destoryWebView(); super.destroy(); } private void destoryWebView() { this.stopLoading(); this.removeAllViews(); if(this.getParent()!=null){ //处理webview无法释放造成的内存泄漏,必须在destroy之前调用 ViewGroup parent = (ViewGroup) this.getParent(); parent.removeView(this); setConfigCallback(null); } } public void setConfigCallback(WindowManager windowManager) { try { if(Build.VERSION.SDK_INT>15) { return; } Field field = WebView.class.getDeclaredField("mWebViewCore"); field = field.getType().getDeclaredField("mBrowserFrame"); field = field.getType().getDeclaredField("sConfigCallback"); field.setAccessible(true); Object configCallback = field.get(null); if (null == configCallback) { return; } field = field.getType().getDeclaredField("mWindowManager"); field.setAccessible(true); field.set(configCallback, windowManager); } catch(Exception e) { e.printStackTrace(); return; } }
参考:
https://www.jianshu.com/p/eada9b652d99 https://blog.csdn.net/xygy8860/article/details/53334476?utm_source=itdadao&utm_medium=referral https://stackoverflow.com/questions/11995270/error-webview-destroy-called-while-still-attached/12408703#12408703 https://www.jianshu.com/p/c2412918b2b5
org.chromium.android_webview.AwContents源码https://github.com/pwnall/chromeview/blob/master/src/org/chromium/android_webview/AwContents.java
https://chromium.googlesource.com/chromium/src/android_webview/glue/+/master/java/src/com/android/webview/chromium/WebViewContentsClientAdapter.java
2、SSL证书处理
https://blog.csdn.net/zoeice/article/details/139965793、常见问题处理
史上最全WebView使用,附送Html5Activity一份4.onPageFinished被调用多次
使用onPageProgressChanged代替private void handleProgress(WebView view, int newProgress){ if(progressPending.get()!=newProgress){ progressPending.set(newProgress); onProgressChanged(newProgress); } } @Override public final void onProgressChanged(WebView view, int newProgress) { super.onProgressChanged(view, newProgress); handleProgress(view,newProgress); } public void onProgressChanged(int newProgress){ Log.i("WebChromeClient","progress="+newProgress+"%"); if(newProgress==100){ Log.i("WebChromeClient","加载完成"); } }
5.WebChromeClient接口中onReceiveTitle返回的标题是url
解决方法如下@Override public final void onReceivedTitle(WebView view, String title) { super.onReceivedTitle(view, title); handleProgress(view,view.getProgress()); if(URLUtils.isNetworkUrl(title)){ return; } if(!TextUtils.isEmpty(title) && !TextUtils.isEmpty(view.getUrl())&& !view.getUrl().contains(title)){ onReceivedTitle(title); } } public void onReceivedTitle( String title){ }
6.使用ApplicationContext
使用ApplicationContext可以减少对当前Activity的依赖,便于内存释放,但是这里还有一些问题需要处理,比如ApplicationContext不能加载主题,必须通过ContextThemeWrapper加载。此外,如果使用了ApplicationContext时没有设置WebChromeClient的情况下,alert,confirm等对话框无法显示。无法显示的原因可以参考源码:
https://chromium.googlesource.com/chromium/src/android_webview/glue/+/master/java/src/com/android/webview/chromium/WebViewContentsClientAdapter.java
private boolean showDefaultJsDialog(JsPromptResult res, int jsDialogType, String defaultValue, String message, String url) { 如果Context不是一个Activity是不允许显示的 Context activityContext = AwContents.activityFromContext(mContext); if (activityContext == null) { Log.w(TAG, "Unable to create JsDialog without an Activity"); return false; } try { new JsDialogHelper(res, jsDialogType, defaultValue, message, url) .showDialog(activityContext); } catch (WindowManager.BadTokenException e) { Log.w(TAG, "Unable to create JsDialog. Has this WebView outlived the Activity it was created with?"); return false; } return true; }
继承关系图
如果h5页面不适用alert,confirm等,可以使用ApplicationContext,否则建议使用activitiy或者设置WebChromeClient自行实现。这里提供一个使用ApplicaitonContext的例子。
public MyWebView(Context context, AttributeSet attrs) { super(WebThemeContext.wrapper(context), attrs, android.R.attr.webViewStyle); }
public class WebThemeContext extends ContextThemeWrapper { public WebThemeContext ( Context context) { super(MyApplication.getInstance(), context.getTheme()); //设置主题 } public static WebThemeContext wrapper( Context context){ return new WebThemeContext(context); } @Override public Context getApplicationContext() { return getInstance.getInstance(); } }
7.性能监控
https://blog.csdn.net/lmj623565791/article/details/586263558.Android WebView 输入框键盘不弹出
在复写MyView时,使用的主题id必须设置,并且设置为android.R.attr.webViewStyle,否则无法调用native服务,如键盘9.Android Webview是否应该开启硬件加速
由于碎片化问题太多,建议保持默认状态【默认表示由系统决定,不要手动设置】,否则可能产生问题。10.Cookie同步导致的内存泄漏
使用CookieSyncManager同步时,会永久引用第一个acitivity的的Context,为了避免此种情况,请使用ApplicationContextif (Build.VERSION.SDK_INT < 21) { android.webkit.CookieSyncManager.createInstance(context.getApplicationContext()); }
11. 30x重定向问题
Android Webview重定向可能导致Android 5.0和5.0之前的Webview内核死锁,而且会导致资源无法释放。一旦内核死锁,那么整个app必须重启才能加载网页,否则一直处于空白状态。12.loadUrl(url,map)方法加载带hash(带#号)的url导致刷新问题或请求头缓存问题。
① 如果调用loadUrl(url,map)方法去加载资源,那么在此调用loadUrl(ur),reload,loadUrl(url,map)造成无法刷新的问题。这个现象主要出现在Android 8.0的系统中。可尝试调用如下url尝试:
https://baike.baidu.com/item/%E9%83%8E%E5%B9%B3/58857#/ https://baike.baidu.com/item/%E9%83%8E%E5%B9%B3/58857#/?a=123 https://baike.baidu.com/item/%E9%83%8E%E5%B9%B3/58857#3
②loadUrl(url,map) 第二个参数map中传入的数据用于请求头,此外这个请求头数据会被webview缓存下来,刷新时,请求头中的数据还是原来的,因此,不适用传入需要进程变化的“状态”信息。
解决方法:不要使用loadUrl(url,map),推荐使用loadUrl(url),如果非要传输参数,还不如在url中添加参数。
13.Android 4.2.2 系统注入javascript脚本导致页面循环刷新,导致内核闪退。
Android 4.2.2进行了一次内核调整,但是遗留了一部分bug,就是在js脚本注入的时候,必须得添加 “javascript:”前缀,否则页面将无限刷新,最后ANR。因此,这里建议任何脚本,必须添加 "javscript:"前缀。相关文章推荐
- html5[1]:优化Android Webview性能
- Android WebView:性能优化不得不说的事
- Android WebView: 性能优化不得不说的事
- android webview常见问题与性能优化
- android WebView性能优化
- Android WebView 性能优化
- android webview性能优化
- Android WebView:性能优化
- Android WebView开发问题及优化汇总
- [转载]Android利用convertView优化ListView性能
- WebView性能、体验分析与优化(转载)
- Android性能优化之:ViewStub
- Android性能优化之ViewStub
- Android 使用TBS提高WebView的兼容性和性能
- Android WebView开发问题及优化汇总
- Android-WebView优化
- Android WebView开发问题及优化汇总
- android之 listview加载性能优化ViewHolder
- Android性能优化之一:ViewStub
- Android WebView开发问题及优化汇总