前言:WebView是Android里比较特殊的一个控件,是Android混合开发(原生开发+web开发)的基础。笔者目前开发的项目,用到WebView地方还是比较多的,遇到了不少坑,为了避免遇到类似的问题,今天在这里针对webView做一篇系统的归纳总结,希望对别人能有帮助。
WebView是基于webkit引擎、展现web页面的控件,在低版本和高版本采用了不同的webkit版本内核,4.4后直接使用了Chrome。可以用于显示和渲染Web页面,直接展示Html文件(网络或者本地文件),可以和JavaScript交互。

1. webView基本使用;

WebView webView= (WebView) findViewById(R.id.webView);String url="http://go.10086.cn/rd/go/dh/";webView.loadUrl(url);

这种基本使用可以实现webView加载网页或者本地Html文件,但是存在一个问题,当在网页中点击进入下一个网页的时候,会自定跳转到手机系统浏览器中加载的,这种用户体验往往是非常不友好的,无论加载多少网页,始终在自己开发的app内,才是一个有逼格(文字捂脸)的开发人员,应该实现的,代码修改为:

WebView webView= (WebView) findViewById(R.id.webView);        String url="http://go.10086.cn/rd/go/dh/";        webView.loadUrl(url);        webView.setWebViewClient(new WebViewClient(){            @Override            public boolean shouldOverrideUrlLoading(WebView view, String url) {                view.loadUrl(url);//                return false;//这里笔者测试的时候,返回false和true效果是一样的                //所有网页都是在程序中进行加载的TODO                return true;            }        });

如果没有什么特殊要求,基本上上面代码就可以实现我们日常加载网页的基本需求。但是我们混合开发往往没有那么简单,或者需要在网页中录入信息,加载图片,如果js中有缓存问题,Android端没有进行相应的设置,会出现很多问题,下面是一些常用设置,后面都有详细说明。

2. webView 常用设置项;

WebSettings ws = webView.getSettings();        //以下两条共同设置网页适应手机屏幕        ws.setUseWideViewPort(true);//设置网页图片适用手机屏幕,适应webView;        ws.setLoadWithOverviewMode(true);//设置网络缩小至屏幕大小        // 设置此属性,可任意比例缩放。        ws.setUseWideViewPort(true);        // 缩放比例 1        webView.setInitialScale(100);        //设置字符        ws.setDefaultTextEncodingName("utf-8");        //缩放操作        ws.setSupportZoom(true); //支持缩放,默认为true。是下面那个的前提。        ws.setBuiltInZoomControls(true); //设置内置的缩放控件。若为false,则该WebView不可缩放        ws.setDisplayZoomControls(false); //隐藏原生的缩放控件        // 启动应用缓存        ws.setAppCacheEnabled(true);        ws.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN);        //其他细节操作#########################        //缓存模式如下:        //LOAD_CACHE_ONLY: 不使用网络,只读取本地缓存数据        //LOAD_DEFAULT: (默认)根据cache-control决定是否从网络上取数据。        //LOAD_NO_CACHE: 不使用缓存,只从网络获取数据.        //LOAD_CACHE_ELSE_NETWORK,只要本地有,无论是否过期,或者no-cache,都使用缓存中的数据。(没有网络则从本地获取)        ws.setCacheMode(WebSettings.LOAD_NO_CACHE); //关闭webview中缓存(不使用本地缓存,否则部分弹窗不消失)        // 使用localStorage则必须打开&&&&&&&这个必须加上        /**         * 这个属性不添加遇到的坑:         * 坑1:如果js那边添加本地缓存,没有设置这个属性,会导致js代码执行出现异常         * 坑2:没有下面这条,h5中使用的css标签实现的弹窗功能异常,不消失一直旋转,加上之后正常(感觉是不是也是因为js那边加了缓存)         */        ws.setDomStorageEnabled(true);        // setDefaultZoom  api19被弃用        // 告诉WebView启用JavaScript执行。默认的是false。        ws.setJavaScriptEnabled(true);        //  页面加载好以后,再放开图片  这个建议设置为false,如果设置为true,图片容易加载不出来        ws.setBlockNetworkImage(false);//         排版适应屏幕        ws.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NARROW_COLUMNS);        // WebView是否支持多个窗口。        ws.setSupportMultipleWindows(true);        // webview从5.0开始默认不允许混合模式,https中不能加载http资源,需要设置开启。        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {            ws.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);        }        //设置字体默认缩放大小(改变网页字体大小,setTextSize  api14被弃用)        //值为100的时候正常        ws.setTextZoom(100);

上面是关于WebView一些常用的设置,可以参考自己的需求进行设置,笔者建议全部加上,反正复制粘贴的问题,避免以后使用出现各种意外情况,特别缓存那块。

3. 深入使用

3.1 Js调用Android代码
Android 端部分代码实现如下:

  `````private void loadUrl(String url) {    if (TextUtils.isEmpty(url)) {        ToastUtils.makeLongText(this, "开户路径是空");        return;    }    //开启JavaScript支持    WebSettings webSettings = webView.getSettings();    webSettings.setJavaScriptCanOpenWindowsAutomatically(true);    webSettings.setUseWideViewPort(true);//设置webview推荐使用的窗口    webSettings.setLoadWithOverviewMode(true);//设置webview加载的页面的模式    webSettings.setDisplayZoomControls(false);//隐藏webview缩放按钮    webSettings.setJavaScriptEnabled(true); // 设置支持javascript脚本    webSettings.setAllowFileAccess(true); // 允许访问文件    webSettings.setBuiltInZoomControls(true); // 设置显示缩放按钮    webSettings.setSupportZoom(true); // 支持缩放    //没有下面这条,h5中使用的css标签功能异常,加上之后正常  #########################    webSettings.setDomStorageEnabled(true);//解决部分标签不支持的问题    //LOAD_CACHE_ONLY: 不使用网络,只读取本地缓存数据    //LOAD_DEFAULT: (默认)根据cache-control决定是否从网络上取数据。    //LOAD_NO_CACHE: 不使用缓存,只从网络获取数据.    //LOAD_CACHE_ELSE_NETWORK,只要本地有,无论是否过期,或者no-cache,都使用缓存中的数据。(没有网络则从本地获取)    webSettings.setCacheMode(WebSettings.LOAD_NO_CACHE); //关闭webview中缓存(不使用本地缓存,否则部分弹窗不消失)    webView.getSettings().setJavaScriptEnabled(true);    //放在assets的html需加上android_asset/  也可以用网络上的文件    webView.setWebViewClient(new WebViewClient() {        //覆盖shouldOverrideUrlLoading 方法        @Override        public boolean shouldOverrideUrlLoading(WebView view, String url) {            view.loadUrl(url);            return true;        }    });    webView.loadUrl(url);   // 添加一个对象, 让JS可以访问该对象的方法, 该对象中可以调用JS中的方法    webView.addJavascriptInterface(new JSInterface1(), "android");}  ````` ``````  class JSInterface1 {    //JavaScript调用此方法  //笔者测试发现,该方法在非主线程中执行如果在方法中,直接修改Ui,系统会抛出异常;(汗颜,道行尚欠)    @JavascriptInterface    public void back() {   //mHandler在主线程中创建对象       mHandler.post(new Runnable() {            @Override            public void run() {                EventBus.getDefault().post(new EventBusPersonInfoList("123"));                finish();            }        });    }}

3.2 Android调用js代码
这个部分目前笔者项目中还没有涉及到过,曾将尝试写个demo测试一下,由于前端代码不是很精通,没有实现,所以这里就不过多贴代码了,后面项目中用到之后,立即补充。
3.3 webView加载网页进度条实现
笔者目前通过学习webView相关知识了解到,webView加载进度条的实现方式有两种:
方式一:旋转的进度实现,页面加载开始弹出,页面渲染完毕后消失,实现方式如下

webView.setWebViewClient(new WebViewClient() {                @Override                public void onPageStarted(WebView view, String url, Bitmap favicon) {                    super.onPageStarted(view, url, favicon);                    showWaitDialog();                }                @Override                public void onPageFinished(WebView view, String url) {                    super.onPageFinished(view, url);                    dismissDialog();                }                //覆盖shouldOverrideUrlLoading 方法                @Override                public boolean shouldOverrideUrlLoading(WebView view, String url) {                    view.loadUrl(url);                    return false;                }            });

方式二:类似网页加载中,页面加载上面有个横向的进度条,根据网络渲染进度,加载进度条进度

webview.setWebChromeClient(new WebChromeClient(){            @Override            public void onProgressChanged(WebView view, int newProgress) {                super.onProgressChanged(view, newProgress);                //在这里可以可以加载进度进度条进度            }        });
  1. 销毁处理
    为了避免webView造成内存卸载,需要在页面销毁的同时销毁webView,
    如下所示
@Override    protected void onDestroy() {        if (mWebView != null) {            mWebView.loadDataWithBaseURL(null, "", "text/html", "utf-8", null);            mWebView.clearHistory();            ((ViewGroup) mWebView.getParent()).removeView(mWebView);            mWebView.destroy();            mWebView = null;        }        super.onDestroy();    }

总结

写这篇文章的过程中,其实是一个知识总结记录,内心反思的过程,老实说,写这篇文章的时候,笔者内心是比较心虚的,为啥呢,说实话,我看过很多前辈写的关于WebView相关的文章,写得非常好,非常深入,文章中,既说明了怎么做,还说明了为啥这么做,对比自己写的这边文章,感觉自己太low了,但是思前想后,还是要写这篇文章,万事开头难,越不写,越不敢写,越不会写,所以一定要写,只有写才会有提高。
最后关于这篇文章,无论知识的广度还是深度,都是比较皮毛的,这篇文章重点是记录自己工作中遇到的问题,能够帮助其他,笔者非常感到荣幸,但愿不会误人子弟(捂脸),文章有任何不对不足的地方,欢迎各位留言斧正,谢谢!
下面是自己学习webView相关文章,仅供参考:
关于webView常见Api最详尽介绍
关于webView和android互相调用
关于webView使用漏洞
关于webView详尽介绍

更多相关文章

  1. Android:这是一份全面 & 详细的Webview使用攻略
  2. Android成长之路之layout加载过程
  3. Android异步加载之AsyncTask
  4. Android(安卓)ImageView的scaleType属性作用
  5. Mosby -- Android上的MVP框架
  6. App混合开发之WebView进行H5页面基本操作
  7. Android(安卓)轻量级缓存框架ASimpleCache分析
  8. Android(安卓)WebView用法和WebView加载提升网页速度
  9. 【多媒体编解码】Openmax IL (二)Android多媒体编解码Component架

随机推荐

  1. Android(安卓)如何避免(降低)后台程序被杀?
  2. 如何查看Android(安卓)中native的Service
  3. Android下的扩展SeekBar
  4. Android(安卓)HTTP session && cookie
  5. Android调试工具 MAT
  6. Android(安卓)之 下拉框(Spinner)的简单
  7. Android(安卓)Studio 使用过程中的坑
  8. 【展讯平台】Android(安卓)驱动(Kernel)
  9. 打开和关闭WIFI 的代码出现了问题 androi
  10. BroadcastReceiver与LocalBroadcastManag