webview整理

来源:互联网 发布:paparecipe防伪软件 编辑:程序博客网 时间:2024/05/29 16:25

转自http://blog.csdn.net/publicperson/article/details/73498099

博主是我老乡,本着发扬家乡文化的精神,看都没看就直接转载了得意

 在这家公司做混合开发已经半年了,接触webview也半年了,期间也体验了crosswalk和TBS等三方,但也有各种各样的问题,最终还是选择了原生webview。对于这系列文章也早有心事,好记性不如烂笔头,但发表到网上又怕别人看到,因为自己理解不够误导大家,所以迟迟没有开始,但随着知识点越来越多,慢慢的就真的有东西记不住了,所以就抓紧写了这系列播客,如有错误请批评,如有帮助,不胜荣幸。


一、动态添加删除webview控件


    提到webview最先想到内存泄漏的问题,而解决这个问题最常说到的就是动态添加删除。

a)动态添加:将xml文件中的webview控件用LinearLayout代替,在java代码中初始化webview,添加到LinearLayout中,代码如下

xml布局:

[html] view plain copy
  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2. xmlns:tools="http://schemas.android.com/tools"  
  3. android:id="@+id/activity_main"  
  4. android:layout_width="match_parent"  
  5. android:layout_height="match_parent"  
  6. android:fitsSystemWindows="true">  
  7.   
  8. <LinearLayout  
  9. android:id="@+id/linear"  
  10. android:layout_width="match_parent"  
  11. android:layout_height="match_parent"  
  12. android:orientation="vertical" />  
  13. </RelativeLayout>  



java代码:

[java] view plain copy
  1. LinearLayout linear = (LinearLayout) findViewById(R.id.linear);  
  2. LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);  
  3. WebView web = new WebView(getApplicationContext());  
  4. web.setLayoutParams(params);  
  5. 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就好了:

[java] view plain copy
  1. @Override  
  2. protected void onPause() {  
  3. super.onPause();  
  4. if (web != null) {  
  5. web.onPause();  
  6. }  
  7. }  
  8.   
  9. @Override  
  10. protected void onResume() {  
  11. super.onResume();  
  12. if (web != null) {  
  13. web.onResume();  
  14. }  
  15. }  
  16.   
  17. //退出程序  
  18. @Override  
  19. protected void onDestroy() {  
  20. super.onDestroy();  
  21. if (web != null) {  
  22. web.loadDataWithBaseURL(null"""text/html""utf-8"null);  
  23. web.clearHistory();  
  24. if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {  
  25. if (linear != null) {  
  26. linear.removeView(web);  
  27. }  
  28. web.removeAllViews();  
  29. web.destroy();  
  30. else {  
  31. web.removeAllViews();  
  32. web.destroy();  
  33. if (linear != null) {  
  34. linear.removeView(web);  
  35. }  
  36. }  
  37. web = null;  
  38. }  
  39. }  



    至此webview控件就算摆上了,接下来就是呈现web页面了,好啦,让我们踩下一个大坑。。。

二、加载适配

    a)加载:webview加载web页面的方法差不多都知道,就简单写一下:

[java] view plain copy
  1. webView.loadUrl("http://www.google.com");//加载网络web页面  
  2. webView.loadUrl("file:///android_asset/XX.html"); //加载本地web页面  

没啥好说的,基本都知道,这个不会自动在自己的app中呈现,需要如下操作:
[java] view plain copy
  1. webView.setWebViewClient(new WebViewClient());  

也可以自定义一个类集成WebViewClient,然后重写其中方法,括号中初始化自定义的类,如果只是呈现,用不到其中过多方法这样写也行。

    b)适配:这个地方工作就开始多了,要分开讲了:

    1)设置web适应屏幕呈现

    主要就是两行代码:


[java] view plain copy
  1. WebSettings webSettings = webView.getSettings();//获取WebSetting,这里面有很多适配webview的方法  
  2.   
  3. webSettings.setUseWideViewPort(true); //设置webview推荐使用的窗口webSettings.setLoadWithOverviewMode(true);//设置加载模式自适应  




也有别的类似功能的方法,以前我就是用那个方法的,后来发现弊病很多,就改成这两个了。

2)控制图片加载


按照以上方法做出来,web页面加载出来有时还会乱,这时候我们就可以加上如下方法


[java] view plain copy
  1. //告诉WebView先不要自动加载图片,等页面finish后再发起图片加载API19  
  2.   
  3. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {  
  4. webSettings.setLoadsImagesAutomatically(true);  
  5. else {  
  6. webSettings.setLoadsImagesAutomatically(false);  
  7. }  





3)硬件辅助

其实做完这些工作页面大体可以了,但有时还会有个别错位,这时候就可以在清单配置文件开启硬件加速,还可以顺便在这里增加内存申请量(Android并不支持增加内存申请量,只有像我这样小菜才会很少考虑的增加),操作如下:


[java] view plain copy
  1. <application  
  2. android:hardwareAccelerated="true"//开启硬件加速  
  3. android:largeHeap="true"//增加内存申请量  
  4. > </application>  



硬件加速可以优化适配,提升速度,但也不是没有坏处,据说会让自定义view变花,总之,如果没有缺点,就不会必须手动开了,在这里我们也简单管理一下:


[java] view plain copy
  1. //在过渡期前将WebView的硬件加速临时关闭,过渡期后再开启  
  2.   
  3. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {  
  4. webView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);  
  5. }  



4)其它方法

有人说webview是最难控件,我觉得也差不多,他的坑数不胜数,各种方法,很难全部掌握,再简单举几个方法,记录一下:

[java] view plain copy
  1. //将密码保存在WebView,此方法在API 18时被弃用。  
  2. if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {  
  3. webSettings.setSavePassword(true);//设置保存密码  
  4. }  
  5. //Android安全问题  
  6. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {  
  7. webSettings.setAllowUniversalAccessFromFileURLs(true);  
  8. }  
  9. //用于chrome调试  
  10. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {  
  11. WebView.setWebContentsDebuggingEnabled(true);  
  12. }  
  13. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {  
  14. CookieManager cookieManager = CookieManager.getInstance();  
  15. cookieManager.setAcceptCookie(true);  
  16. cookieManager.setAcceptThirdPartyCookies(webView, true);  
  17. webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);  
  18. }  
  19. //还有控制webview的ScrollBar显示的方法:  
  20. webView.setHorizontalScrollBarEnabled(false);  
  21. webView.setVerticalScrollBarEnabled(false);  






差不多这些方法一怼,web页面就呈现的差不多了。我在开始这份工作的时候,网上对于webview的讲解少之又少,那时候解决个问题真的是很累,最近倒是出了几篇讲的比较全的博文,但是我感觉和这个系列侧重点不同,那些作者能力很强,注重方法讲解,我则是讲一个混合项目一点点的做出来,完善,如有瑕疵,敬请赐教,如有帮助,不胜荣幸