博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
android WebView使用详解及各种设置说明
阅读量:4179 次
发布时间:2019-05-26

本文共 9471 字,大约阅读时间需要 31 分钟。

对于现在的App来说,内嵌一些web网页是比较常见的了,如果只是简单的使用,那是很简单的,直接使用webview加载url就可以了,但是有时还是会涉及到各种不同的需求,这时就要求我们去设置一些参数以及会做不同的处理。

这里会从四个方面来说:

1、WebView的简单使用;

2、WebView使用WebSettings的各种设置;

3、WebView使用WebViewClient各种方法的作用;

4、WebView使用WebViewChrome各种方法的作用;

  • WebView使用

1、对于WebView的使用首先是来看他是如何加载各种资源的:

//方式1. 加载一个网页:  webView.loadUrl("http://www.baidu.com/");  //方式2:加载apk包中的html页面  webView.loadUrl("file:///android_asset/web/test.html");  //方式3:加载手机本地的html页面,这里需要注意在高版本中文件权限申请,如果没有权限会报ERR_ACCESS_DENIED   webView.loadUrl("file://"+Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "test.html");   // 方式4: 加载 HTML 页面的一小段内容  webView.loadDataWithBaseURL(null,content,"text/html","utf-8",null);

目前这里只是加载了资源文件,并没有做任何的设置,显示效果肯定是不如意的,比如显示的界面可以左右滑动,这肯定不是我们想要的效果,我们想要的肯定是显示的界面正好适配手机屏幕,这就需要使用到WebViewSettings了,后面会讲到。

2、管理WebView的生命周期:

为了配合Activiyt的生命周期,WebView也有相对应的生命周期,接下来就一起来看看:

//激活WebView为活跃状态,能正常执行网页的响应webView.onResume() ;//当页面被失去焦点被切换到后台不可见状态,需要执行onPause//通过onPause动作通知内核暂停所有的动作,比如DOM的解析、plugin的执行、JavaScript执行。webView.onPause();//当应用程序(存在webview)被切换到后台时,这个方法不仅仅针对当前的webview而是全局的全应用程序的webview//它会暂停所有webview的layout,parsing,javascripttimer。降低CPU功耗。webView.pauseTimers()//恢复pauseTimers状态webView.resumeTimers();//销毁Webview//在关闭了Activity时,如果Webview的音乐或视频,还在播放。就必须销毁Webview//但是注意:webview调用destory时,webview仍绑定在Activity上//这是由于自定义webview构建时传入了该Activity的context对象//因此需要先从父容器中移除webview,然后再销毁webview:rootLayout.removeView(webView); webView.destroy();

3、清理缓存:

//清除网页访问留下的缓存//由于内核缓存是全局的因此这个方法不仅仅针对webview而是针对整个应用程序.Webview.clearCache(true);//清除当前webview访问的历史记录//只会webview访问历史记录里的所有记录除了当前访问记录Webview.clearHistory();
  • WebViewSettings常见设置

上面讲到WebView并没有说到它的设置,比如如何将加在的资源正好可以适配手机的屏幕,如何才能对WebView进行缩放,又要如何缓存等等,这一系列的问题都是可以通过WebViewSettings来进行设置,下来就一起来看看:

1、如何获取WebViewSettings:

WebView webView = findViewById(R.id.wb_content);WebSettings webSettings = webView.getSettings();

2、适配手机屏幕:

// 设置网页自动适配//if(Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT){//小于4.4(不包括4.4)用这个//      webSettings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN);//}// 这个是设置WebView是否支持ViewPort属性,// ViewPort是在html中配置,主要为了适配各种屏幕,如果html中有配置这个属性,那么即使不设置这个属性也是会适配屏幕的// 注意:当html中有这个属性时,WebView设置缩放属性是不起作用的webSettings.setUseWideViewPort(true);// 当html中没有配置ViewPort这个属性时,同时还需要设置下面这个属性才能适配屏幕webSettings.setLoadWithOverviewMode(true);

html配置ViewPort如下:

简书ViewPort配置:
CSDN ViewPort配置:

关于ViewPort的讲解可以自行百度。

3、设置字体内容的大小:

//设置字体的大小,100是默认大小,200是字体放大了一倍webSettings.setTextZoom(100);

4、设置缓存模式:

// LOAD_DEFAULT:系统默认的缓存模式,有缓存且缓存没有过期,那么就使用缓存,否则就从网络上获取// LOAD_CACHE_ELSE_NETWORK:只要有缓存,不管缓存有没有过期都是使用缓存,没有缓存就从网络上获取// LOAD_NO_CACHE:不管有没有缓存都是从网络上获取// LOAD_CACHE_ONLY:只从缓存中获取,不会从网络上获取webSettings.setCacheMode(WebSettings.LOAD_DEFAULT);

对于缓存还存在其他几种设置,不过对于android来说,只需要设置其功能开启就行,一般都是在h5中做缓存处理:

4.1、Dom Storage(Web Storage)缓存:

webSettings.setDomStorageEnabled(true);

4.2、Web SQL Database 缓存:

webSettings.setDatabaseEnabled(true);//设置缓存,可不用设置,使用系统默认路径webSettings.setDatabasePath("path");

4.3、Application Cache(AppCache)缓存:

webSettings.setAppCacheEnabled(true);// 不设置,使用系统默认的路径webSettings.setAppCachePath("path");

4.4、indexed Database(IndexedDb)缓存:

webSettings.setJavaScriptEnabled(true);

这里只是说到了开启缓存的一些设置,对于这些缓存的具体含义可以参考:

5、使页面具有缩放功能,前提是html中没有配置ViewPort属性:

// 使页面具有缩放功能,在缩放的同时显示缩放按钮webSettings.setBuiltInZoomControls(true);// 多方功能开始时,隐藏缩放按钮(按钮看起来很丑)webSettings.setDisplayZoomControls(false);

6、是否允许WebView加载不安全的链接:

// MIXED_CONTENT_NEVER_ALLOW:不安全的链接全部不允许加载,android 5.1默认// MIXED_CONTENT_ALWAYS_ALLOW:不安全的链接总是允许加载,android 4.4及以下默认// MIXED_CONTENT_COMPATIBILITY_MODE:不安全的链接询问用户书否允许加载// 注意:android 5.1默认禁止http和https混合调用,需用下面设置开启webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);

 7、开启前端代码和android本地代码互调:

webSettings.setJavaScriptEnabled(true);
  • WebViewClient使用

WebViewSettings中的设置,并没有涉及到网络加载的一些逻辑,对于网络加载,必定是耗时的,这时为了更好的交互效果,肯定是需要一个加载的显示动画的,而且,有时想对网页中的部分链接进行拦截,这时又该怎么做呢?这时就该WebViewClient上场了。

1、当已经加载一个网页了,这时点击网页上的连接数时,这时就会跳转到系统的浏览器,这肯定不是我们想见到的,我们肯定是想让新加载的网页还是在我们的应用中显示,这时就需要设置WebViewClient:

webView.setWebViewClient(new WebViewClient());

这样设置后,点击网页中的链接时,就不会将事件交由系统去处理,而是会让我们的应用来处理,也就说新的点击事件将会交由我们的WebView来处理;

2、网页开始加载和结束加载回调:

webView.setWebViewClient(new WebViewClient(){            @Override            public void onPageStarted(WebView view, String url, Bitmap favicon) {                super.onPageStarted(view, url, favicon);                Log.d(TAG, "onPageStarted: 我开始加载玩网页了,你可以显示加载动画了");            }            @Override            public void onPageFinished(WebView view, String url) {                super.onPageFinished(view, url);                Log.d(TAG, "onPageFinished: 加载网页结束了,你可以取消加载动画了,但图片资源未必加载完成了");            }        });

3、当我点击网页上的链接时,我想自己处理,而不是交由应用的WebView去处理:

webView.setWebViewClient(new WebViewClient(){            @Override            public boolean shouldOverrideUrlLoading(WebView view, String url) {                if (url.equals("targetUrl")){                    Log.d(TAG, "shouldOverrideUrlLoading: 这里就需要你自己做逻辑处理了,系统并不会去加载资源");                    return true;                } else {                    Log.d(TAG, "shouldOverrideUrlLoading: 返回false,意味着应用不做处理,交由WebView去处理");                    return false;                }            }        });

这里的返回值就说明了点击链接的事件是交由谁去处理,返回true,WebView不会处理,需要我们自己处理,返回false的话WebView会去处理,这是我们就不需要做多余的处理了;

4、加载Web网页时,加载的并不只是一个请求,会有很多的请求去执行,比如一张图片就是一个请求,一份Css资源也是一个请求等,这时,如果想对这些url进行拦截,这也是可以做到的:

webView.setWebViewClient(new WebViewClient(){            @Nullable            @Override            public WebResourceResponse shouldInterceptRequest(WebView view, String url) {                if (url.equals("targetUrl")) {                    InputStream data = null;                    WebResourceResponse response = new WebResourceResponse("text/html","utf-8",null);                    Log.d(TAG, "shouldInterceptRequest: 这里data返回的是null,可以根据需要返回," +                            "这样就不会再去网络上加载对应url资源了,也就不会再去执行下面的onLoadResource()方法了");                    return response;                } else {                    Log.d(TAG, "shouldInterceptRequest: 没有拦截,会调用到下面的onLoadResource()方法");                    return null;                }            }            @Override            public void onLoadResource(WebView view, String url) {                super.onLoadResource(view, url);                Log.d(TAG, "onLoadResource: 需要去加载的资源都会执行到这里");            }        });

5、对于网页的加载,有时候各种出错的问题都是会有的,我这里总结下我测试过的一些错误处理:

webView.setWebViewClient(new WebViewClient(){            @Override            public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {                super.onReceivedError(view, errorCode, description, failingUrl);                if (errorCode == -1) {                    Log.d(TAG, "onReceivedError: 加载本地文件时,文件没有找到");                } else if (errorCode == -2) {                    Log.d(TAG, "onReceivedError: 没有连接网络或是找不到服务器");                }            }            @Override            public void onReceivedHttpError(WebView view, WebResourceRequest request, WebResourceResponse errorResponse) {                super.onReceivedHttpError(view, request, errorResponse);                if (errorResponse.getStatusCode() == 404) {                    Log.d(TAG, "onReceivedHttpError: 只有在android 6.0以上的系统才发触发到这里");                }            }        });

注意:这里对于404的处理,目前只在6.0以上的系统才能接收到,所以针对6.0以下的系统是需要我们另想办法的。

  • WebChromeClient使用

WebChromClient是WebView的一个辅助类,可以获取h5页面的的标题,图片以及对话框,利用这个对话框的特性,可以方便android与前端的交互,有好些框架就是利用了这个特性,同时,还可以监听到h5页面的加载进度。

1、网页加载进度:

webView.setWebChromeClient(new WebChromeClient(){            @Override            public void onProgressChanged(WebView view, int newProgress) {                super.onProgressChanged(view, newProgress);                Log.d(TAG, "onProgressChanged: 加载进度 = "+newProgress);            }        });

2、获取网页标题:

webView.setWebChromeClient(new WebChromeClient(){            @Override            public void onReceivedTitle(WebView view, String title) {                super.onReceivedTitle(view, title);                Log.d(TAG, "onReceivedTitle: 网页的标题是 = "+title);            }        });

3、对于h5中的对话框,可以分为三种,一是Alert;二是confirm;三是prompt,当在h5页面中执行这三种对话框时,WebChromeClient也会有相应的方法执行,这是我们就可以做我们自己的逻辑了:

webView.setWebChromeClient(new WebChromeClient(){            @Override            public boolean onJsAlert(WebView view, String url, String message, JsResult result) {                Log.d(TAG, "onJsAlert: h5页面执行Alert对话框了");                return super.onJsAlert(view, url, message, result);            }            @Override            public boolean onJsConfirm(WebView view, String url, String message, JsResult result) {                Log.d(TAG, "onJsConfirm: h5页面执行confirm对话框了");                return super.onJsConfirm(view, url, message, result);            }            @Override            public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) {                Log.d(TAG, "onJsPrompt: h5页面执行prompt对话框了");                return super.onJsPrompt(view, url, message, defaultValue, result);            }        });

这三个方法返回值都是boolean值,返回true意味着我们做了处理,返回false则说明我们没有处理,可根据实际需求进行处理。

总结:

对于WebView的使用,涉及到的四个类都已经说到了,再做个总结 :

  • 如何避免内存泄露

@Overrideprotected 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();    }

 

 

转载地址:http://fkhai.baihongyu.com/

你可能感兴趣的文章
图文介绍openLDAP在windows上的安装配置
查看>>
Pentaho BI开源报表系统
查看>>
Pentaho 开发: 在eclipse中构建Pentaho BI Server工程
查看>>
android中SharedPreferences的简单例子
查看>>
android中使用TextView来显示某个网址的内容,使用<ScrollView>来生成下拉列表框
查看>>
andorid里关于wifi的分析
查看>>
Hibernate和IBatis对比
查看>>
Spring MVC 教程,快速入门,深入分析
查看>>
Android 的source (需安装 git repo)
查看>>
Ubuntu Navicat for MySQL安装以及破解方案
查看>>
java多线程中的join方法详解
查看>>
在C++中如何实现模板函数的外部调用
查看>>
HTML5学习之——HTML 5 应用程序缓存
查看>>
HTML5学习之——HTML 5 服务器发送事件
查看>>
SVG学习之——HTML 页面中的 SVG
查看>>
SVG 滤镜学习之——SVG 滤镜
查看>>
mysql中用命令行复制表结构的方法
查看>>
hbase shell出现ERROR: org.apache.hadoop.hbase.ipc.ServerNotRunningYetException
查看>>
让代码变得更优雅-Lombok
查看>>
解决Rhythmbox乱码
查看>>