转自http://blog.youkuaiyun.com/publicperson/article/details/73498099
博主是我老乡,本着发扬家乡文化的精神,看都没看就直接转载了
在这家公司做混合开发已经半年了,接触webview也半年了,期间也体验了crosswalk和TBS等三方,但也有各种各样的问题,最终还是选择了原生webview。对于这系列文章也早有心事,好记性不如烂笔头,但发表到网上又怕别人看到,因为自己理解不够误导大家,所以迟迟没有开始,但随着知识点越来越多,慢慢的就真的有东西记不住了,所以就抓紧写了这系列播客,如有错误请批评,如有帮助,不胜荣幸。
一、动态添加删除webview控件
提到webview最先想到内存泄漏的问题,而解决这个问题最常说到的就是动态添加删除。
a)动态添加:将xml文件中的webview控件用LinearLayout代替,在java代码中初始化webview,添加到LinearLayout中,代码如下
xml布局:
< RelativeLayout xmlns:android = "http://schemas.android.com/apk/res/android" xmlns:tools = "http://schemas.android.com/tools" android:id = "@+id/activity_main" android:layout_width = "match_parent" android:layout_height = "match_parent" android:fitsSystemWindows = "true" > < LinearLayout android:id = "@+id/linear" android:layout_width = "match_parent" android:layout_height = "match_parent" android:orientation = "vertical" /> </ RelativeLayout >
java代码:
LinearLayout linear = (LinearLayout) findViewById(R.id.linear); LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); WebView web = new WebView(getApplicationContext()); web.setLayoutParams(params); linear.addView(activity_main_web);
这里需要注意两点,一是
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); 这句话一定要添加,我前一阵子看一篇文章没有加这一句,如果你适配的web页面是百度这样的,不添加也能呈现,但是有的web页面就是白屏,还有一个就是 WebView web = new WebView(getApplicationContext()); 初始化Webview用的Context,最好用getApplicationContext,因为用这个更稳定,但是有时弹出弹窗的时候出现app崩溃,报错dialog找不到窗口,指向的不是一个应用,上网查全是告诉你把onJsAlert()方法中自定义dialog初始化用的context改成活动窗口的,而不是Application的,但你用的是窗口还是不行,甚至都没有走这个方法,那你就要问一下,这个弹窗是用什么做的,是不是select下拉列表做的,webview内部不支持select下拉列表,会用一个dialog代替,有的时候也不会有什么问题,但我遇到一种情况,就是在一个web页面上覆盖另一个页面,在点击select app就会崩溃,如果你也遇到这种情况,就把初始化webview的getApplicationContext()换成Activity.this试一下,原因未知,但如果使用没问题,还是建议getApplicationContext()。
b)动态删除:动态删除就比较简单了,直接copy就好了:
@Override protected void onPause() { super .onPause(); if (web != null ) { web.onPause(); } } @Override protected void onResume() { super .onResume(); if (web != null ) { web.onResume(); } } @Override protected void onDestroy() { super .onDestroy(); if (web != null ) { web.loadDataWithBaseURL(null , "" , "text/html" , "utf-8" , null ); web.clearHistory(); if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) { if (linear != null ) { linear.removeView(web); } web.removeAllViews(); web.destroy(); } else { web.removeAllViews(); web.destroy(); if (linear != null ) { linear.removeView(web); } } web = null ; } }
至此webview控件就算摆上了,接下来就是呈现web页面了,好啦,让我们踩下一个大坑。。。
二、加载适配
a)加载:webview加载web页面的方法差不多都知道,就简单写一下:
webView.loadUrl( "http://www.google.com" );//加载网络web页面 webView.loadUrl("file:///android_asset/XX.html" ); //加载本地web页面
没啥好说的,基本都知道,这个不会自动在自己的app中呈现,需要如下操作:
webView.setWebViewClient( new WebViewClient());
也可以自定义一个类集成WebViewClient,然后重写其中方法,括号中初始化自定义的类,如果只是呈现,用不到其中过多方法这样写也行。
b)适配:这个地方工作就开始多了,要分开讲了:
1)设置web适应屏幕呈现
主要就是两行代码:
WebSettings webSettings = webView.getSettings(); webSettings.setUseWideViewPort(true );
也有别的类似功能的方法,以前我就是用那个方法的,后来发现弊病很多,就改成这两个了。
2)控制图片加载
按照以上方法做出来,web页面加载出来有时还会乱,这时候我们就可以加上如下方法
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { webSettings.setLoadsImagesAutomatically(true ); } else { webSettings.setLoadsImagesAutomatically(false ); }
3)硬件辅助
其实做完这些工作页面大体可以了,但有时还会有个别错位,这时候就可以在清单配置文件开启硬件加速,还可以顺便在这里增加内存申请量(Android 并不支持增加内存申请量,只有像我这样小菜才会很少考虑的增加),操作如下:
<application android:hardwareAccelerated="true" android:largeHeap="true" > </application>
硬件加速可以优化适配,提升速度,但也不是没有坏处,据说会让自定义view变花,总之,如果没有缺点,就不会必须手动开了,在这里我们也简单管理一下:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { webView.setLayerType(View.LAYER_TYPE_SOFTWARE, null ); }
4)其它方法
有人说webview是最难控件,我觉得也差不多,他的坑数不胜数,各种方法,很难全部掌握,再简单举几个方法,记录一下:
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) { webSettings.setSavePassword(true ); } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { webSettings.setAllowUniversalAccessFromFileURLs(true ); } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { WebView.setWebContentsDebuggingEnabled(true ); } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { CookieManager cookieManager = CookieManager.getInstance(); cookieManager.setAcceptCookie(true ); cookieManager.setAcceptThirdPartyCookies(webView, true ); webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW); } webView.setHorizontalScrollBarEnabled(false ); webView.setVerticalScrollBarEnabled(false );
差不多这些方法一怼,web页面就呈现的差不多了。我在开始这份工作的时候,网上对于webview的讲解少之又少,那时候解决个问题真的是很累,最近倒是出了几篇讲的比较全的博文,但是我感觉和这个系列侧重点不同,那些作者能力很强,注重方法讲解,我则是讲一个混合项目一点点的做出来,完善,如有瑕疵,敬请赐教,如有帮助,不胜荣幸