WebView使用详解

优势:使用H5实现的功能能够在不升级App的情况下动态更新,而且可以在Android或iOS的App上同时运行,节约了成本,提高了开发效率。

原理:其实就是 Java代码 和 JavaScript 之间的调用。

开局插入一张文章的目录结构:

WebView使用详解

WebView简介

要实现Android与H5互调,WebView是一个很重要的控件,WebView 可以很好地帮助我们展示 html页面,所以有必要先了解一下 WebView。

WebView常用方法

  • loadUrl

加载界面,其次还有 LoadData 和 LoadDataWithBase 方法

//加载assets目录下的test.html文件
webView.loadUrl("file:///android_asset/test.html");
//加载网络资源(注意要加上网络权限)
webView.loadUrl("http://blog.csdn.net");
  • setWebViewClient(如果用户设置了WebViewClient,则在点击新的链接以后就不会跳转到系统浏览器了,而是在本WebView中显示。注意:并不需要覆盖 shouldOverrideUrlLoading 方法,同样可以实现所有的链接都在 WebView 中打开。)

WebViewClient主要用来辅助WebView处理各种通知、请求等事件,通过 setWebViewClient 方法设置。以下是它的几种常见用法:

1. 实现对网页中超链接的拦截(比如如果是极客导航的主页,则直接拦截转到百度主页):

当点击页面中的链接后,会在WebView加载URL前回调 shouldOverrideUrlLoading(WebView view, String url) 方法,一般点击一个链接此方法调用一次。

WebView使用详解

关于 shouldOverrideUrlLoading 返回值的误区:网上很多解释是 return true 代表在本WebView中打开链接,return false代表调用系统浏览器打开链接。其实只要设置了WebViewClient,则就不会调用系统浏览器。

那么 shouldOverrideUrlLoading 的返回值到底代表什么呢?return true,则在打开新的url时WebView就不会再加载这个url了,所有处理都需要在WebView中操作,包含加载;return false,则系统就认为上层没有做处理,接下来还是会继续加载这个url的;默认return false。具体的区别展示如下:

加载百度主页,设置WebViewClient后,重写 shouldOverrideUrlLoading(WebView view, String url) 方法,第一张是返回false的截图(点击后正常跳转),第二张是返回true的截图(点击无反应,如果希望能够跳转,则需要我们自己进行处理):

WebView使用详解

WebView使用详解

还有一点需要注意的是,如果我们拦截了某个url,那么return false 和 return true区别不大,所以一般建议 return false。

2. 加载网页时替换某个资源(比如在加载一个网页时,需要加载一个logo图片,而我们想要替换这个logo图片,用我们assets目录下的一张图片替代)

我们知道我们在加载一个网页的同时也会加载 js,css,图片等资源,所以会多次调用 shouldInterceptRequest 方法,我们可以在 shouldInterceptRequest 中进行图片替换。

注意:shouldInterceptRequest有两个重载:

①public WebResourceResponse shouldInterceptRequest (WebView view, String url) 【已过时】

②public WebResourceResponse shouldInterceptRequest (WebView view, WebResourceRequest request)

这两种方法主要是第二个参数的不同,WebResourceRequest 将能够获取更多的信息,提供了 getUrl(),getMethod,getRequestHeaders 等方法。这里主要是为了展示效果,使用了第一种回调方法。实现方法如下:

WebView使用详解

3. 设置开始加载网页、加载完成、加载错误时处理

WebView使用详解

4. 处理https请求,为 WebView 处理 ssl证书 设置 WebView 默认是不处理https请求的,需要在 WebViewClient 子类中重写父类的 onReceivedSslError 函数

WebView使用详解

  • setWebChromeClient

WebChromeClient主要用来辅助WebView处理Javascript的对话框、网站图标、网站标题以及网页加载进度等。通过WebView的setWebChromeClient()方法设置。

1. 显示页面加载进度在 WebChromeClient 子类中重写父类的 onProgressChanged 函数,progress表示当前页面加载的进度,为1至100的整数

WebView使用详解

2. 加快HTML网页加载完成速度(默认情况html代码下载到WebView后,webkit开始解析网页各个节点,发现有外部样式文件或者外部脚本文件时,会异步发起网络请求下载文件,但如果在这之前也有解析到image节点,那势必也会发起网络请求下载相应的图片。在网络情况较差的情况下,过多的网络请求就会造成带宽紧张,影响到css或js文件加载完成的时间,造成页面空白loading过久。解决的方法就是告诉WebView先不要自动加载图片,等页面finish后再发起图片加载。)

WebView使用详解

  • setDownloadListener

通常webview渲染的界面中含有可以下载文件的链接,点击该链接后,应该开始执行下载的操作并保存文件到本地中。

1. 创建DownloadListener

WebView使用详解

2. 给webview加入监听

webview.setDownloadListener(new MyDownloadListenter());
  • goBack()

返回上一浏览页面,通过重写onKeyDown方法实现点击返回键返回上一浏览页面而非退出程序

WebView使用详解

WebSettings配置

1. 获取WebSettings对象

WebSettings webSettings = webView.getSettings();

2. 常用设置方法

(1) 支持js

settings.setJavaScriptEnabled(true);

(2) 设置缓存方式,主要有以下几种:

  • LOAD_CACHE_ONLY: 不使用网络,只读取本地缓存数据。

  • LOAD_DEFAULT: 根据cache-control决定是否从网络上取数据。

  • LOAD_CACHE_NORMAL: API level 17中已经废弃, 从API level 11开始作用同LOAD_DEFAULT模式。

  • LOAD_NO_CACHE: 不使用缓存,只从网络获取数据。

  • LOAD_CACHE_ELSE_NETWORK:只要本地有,无论是否过期,或者no-cache,都使用缓存中的数据。

settings.setCacheMode(WebSettings.LOAD_NO_CACHE);

(3) 开启DOM storage API功能(HTML5 提供的一种标准的接口,主要将键值对存储在本地,在页面加载完毕后可以通过 JavaScript 来操作这些数据。)

settings.setDomStorageEnabled(true);

(4) 设置数据库缓存路径

settings.setDatabasePath(cacheDirPath);

(5) 设置Application Caches缓存目录

settings.setAppCachePath(cacheDirPath);

(6) 设置默认编码

settings.setDefaultTextEncodingName(“utf-8”);

(7) 将图片调整到适合webview的大小

settings.setUseWideViewPort(false);

(8) 支持缩放

settings.setSupportZoom(true);

(9) 支持内容重新布局

settings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN);

(10) 多窗口

settings.supportMultipleWindows();

(11) 设置可以访问文件

settings.setAllowFileAccess(true);

(12) 当webview调用requestFocus时为webview设置节点

settings.setNeedInitialFocus(true);

(13) 设置支持缩放

settings.setBuiltInZoomControls(true);

(14) 支持通过JS打开新窗口

settings.setJavaScriptCanOpenWindowsAutomatically(true);

(15) 缩放至屏幕的大小

settings.setLoadWithOverviewMode(true);

(16) 支持自动加载图片

settings.setLoadsImagesAutomatically(true);

WebViewClient 的回调方法列表

WebViewClient主要用来辅助WebView处理各种通知、请求等事件,通过setWebViewClient方法设置。

(1) 更新历史记录

doUpdateVisitedHistory(WebView view, String url, boolean isReload)

(2) 应用程序重新请求网页数据

onFormResubmission(WebView view, Message dontResend, Message resend)

(3) 在加载页面资源时会调用,每一个资源(比如图片)的加载都会调用一次。

onLoadResource(WebView view, String url)

(4) 开始载入页面调用,通常我们可以在这设定一个loading的页面,告诉用户程序在等待网络响应。

onPageStarted(WebView view, String url, Bitmap favicon)

(5) 在页面加载结束时调用。同样道理,我们知道一个页面载入完成,于是我们可以关闭loading 条,切换程序动作。

onPageFinished(WebView view, String url)

(6) 报告错误信息

onReceivedError(WebView view, int errorCode, String description, String failingUrl)

(7) 获取返回信息授权请求

onReceivedHttpAuthRequest(WebView view, HttpAuthHandler handler, String host,String realm)

(8) 重写此方法可以让webview处理https请求。

onReceivedSslError(WebView view, SslErrorHandler handler, SslError error)

(9) WebView发生改变时调用

onScaleChanged(WebView view, float oldScale, float newScale)

(10) Key事件未被加载时调用

onUnhandledKeyEvent(WebView view, KeyEvent event)

(11) 重写此方法才能够处理在浏览器中的按键事件。

shouldOverrideKeyEvent(WebView view, KeyEvent event)

(12) 在网页跳转时调用,这个函数我们可以做很多操作,比如我们读取到某些特殊的URL,于是就可以不打开地址,取消这个操作,进行预先定义的其他操作,这对一个程序是非常必要的。

shouldOverrideUrlLoading(WebView view, String url)

(13) 在加载某个网页的资源的时候多次调用(已过时)

shouldInterceptRequest(WebView view, String url)

(14) 在加载某个网页的资源的时候多次调用

shouldInterceptRequest(WebView view, WebResourceRequest request)

注意:

shouldOverrideUrlLoading 在网页跳转的时候调用,且一般每跳转一次只调用一次。

shouldInterceptRequest 只要是网页加载的过程中均会调用,资源加载的时候都会回调该方法,会多次调用。

WebChoromeClient的回调方法列表

WebChromeClient 主要用来辅助WebView处理Javascript的对话框、网站图标、网站标题以及网页加载进度等。通过WebView的setWebChromeClient()方法设置。

(1) 监听网页加载进度

onProgressChanged(WebView view, int newProgress)

(2) 监听网页标题 : 比如百度页面的标题是“百度一下,你就知道”

onReceivedTitle(WebView view, String title)

(3) 监听网页图标

onReceivedIcon(WebView view, Bitmap icon)