一般的,WebView 中的资源检查,我们常会在shouldOverrideUrlLoading
中做一些 Url 的拦截处理,那它和shouldInterceptRequest
有什么不一定的地方呢?
shouldOverrideUrlLoading
的执行时机是当一个新页面即将被打开或重定向时(网页自动重定向或手动点击网页内部链接)。但是此方法不会拦截来自内部的资源加载
,例如,来自 HTML 或 Script 标签中的 iframe 或 src 属性。另外 XmlHttpRequests也不会被拦截,为了拦截这些请求,就可以使用 WebViewClient shouldInterceptRequest
方法。
shouldOverrideUrlLoading
拦截的是url
加载阶段,主要拦截url
shouldInterceptRequest
加载的是响应主体阶段,可拦截url
、js
、css
等
shouldInterceptRequest
为android.webkit.WebViewClient
的成员方法,具体如下:
@Deprecated
public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
return null;
}
/**
* Notify the host application of a resource request and allow the
* application to return the data. If the return value is null, the WebView
* will continue to load the resource as usual. Otherwise, the return
* response and data will be used. NOTE: This method is called on a thread
* other than the UI thread so clients should exercise caution
* when accessing private data or the view system.
*
* <p>Note: when Safe Browsing is enabled, these URLs still undergo Safe Browsing checks. If
* this is undesired, whitelist the URL with {@link WebView#setSafeBrowsingWhitelist} or ignore
* the warning with {@link #onSafeBrowsingHit}.
*
* @param view The {@link android.webkit.WebView} that is requesting the
* resource.
* @param request Object containing the details of the request.
* @return A {@link android.webkit.WebResourceResponse} containing the
* response information or null if the WebView should load the
* resource itself.
*/
public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
return shouldInterceptRequest(view, request.getUrl().toString());
}
其中shouldInterceptRequest(WebView view, String url)
在 API 21 后废弃,shouldInterceptRequest(WebView view, WebResourceRequest request)
为新增的方法,不过本质上还是调用的是前一个方法,虽然已经废弃了,但在实际测试中,低版本、高版本的系统依然可以拦截到加载的资源。
从注释中得知,此方法运行在非 UI 线程中,因此不可在方法中更新 UI,同时也可联想到可以在其中做一些耗时操作,比如下载一份线上的 HTML 文件并加载。
方法返回值默认为null
,返回null
时 WebView 则继续像往常一样加载资源。但是如果你重写了该方法并返回了响应,那么WebView 就会使用你的响应数据。其中WebResourceRequet
封装了请求,WebResourceResponse
封装了响应。
WebResourceResponse
构造方法 | 释义 |
---|---|
WebResourceResponse(String mimeType, String encoding, InputStream data ) |
使用给定的MIME类型,编码和输入流构造资源响应。 |
WebResourceResponse(String mimeType, String encoding, int statusCode, String reasonPhrase, Map<String, String> responseHeaders, InputStream data ) |
用给定的参数构造资源响应。 |
公有方法 | 释义 | 返回值类型 |
---|---|---|
getData() |
获取提供资源响应数据的输入流。 | InputStream |
getEncoding() |
获取资源响应的编码。 | String |
getMimeType() |
获取资源响应的MIME类型。 | String |
getReasonPhrase() |
获取资源响应状态码的描述。 | String |
getResponseHeaders() |
获取资源响应的标题。 | Map<String, String> |
getStatusCode() |
获取资源响应的状态码。 | int |
setData(InputStream data) |
设置提供资源响应数据的输入流。 | void |
setEncoding(String encoding) |
设置资源响应的编码,例如“UTF-8”。 | void |
setMimeType(String mimeType) |
设置资源响应的MIME类型,例如“text / html”。 | void |
代码示例
@Override
public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
// 加载内置资源文件
InputStream inputStream = getResources().getAssets().open(“/asset/xxx”);
// 获取 mimeType
String mimeType = URLConnection.guessContentTypeFromStream(inputStream);
// 返回 WebResourceResponse
return new WebResourceResponse(mimeType, "UTF-8", inputStream);
}
@Override
public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
// 加载存储文件
InputStream inputStream = new BufferedInputStream(new FileInputStream(file));
// 获取 mimeType
String mimeType = URLConnection.guessContentTypeFromStream(inputStream);
// 返回 WebResourceResponse
return new WebResourceResponse(mimeType, "UTF-8", inputStream);
}
@Override
public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
// 加载 HTML
String content = "<html>\n" +
"<title>标题</title>\n" +
"<body>\n" +
"<a href=\"www.baidu.com\">百度</a>,测试连接\n" +
"</body>\n" +
"<html>";
// 返回 WebResourceResponse
return new WebResourceResponse("text/html", "UTF-8", new ByteArrayInputStream(content.getBytes());
}
一些应用场景延伸
-
H5 加载优化,拦截图片的加载请求,加载已经下载好的本地图片,提高加载速度。
-
修改接口请求的入参,如某些场景下,H5 页面内容无法修改,又需要在请求链接上新增参数时,可通过拦截 url,修改后再发起请求,
GET
请求是很容易实现的,POST
请求需要实践。
网友评论