在Android环境下WebView中拦截所有请求并替换URL示例详解
作者:_Hiro 发布时间:2022-05-26 06:21:56
需求背景
接到这样一个需求,需要在 WebView 的所有网络请求中,在请求的url中,加上一个xxx=1的标志位。
例如 http://www.baidu.com 加上标志位就变成了 http://www.baidu.com?xxx=1
寻找解决方案
从 Android API 11 (3.0) 开始,WebView 开始在 WebViewClient 内提供了这样一条 API ,如下:
public WebResourceResponse shouldInterceptRequest(WebView view, String url)
就是说只要实现 WebViewClient 的 shouldInterceptRequest 方法,然后调用 WebView 的setWebViewClient 就可以了。
但是,在 API21 以上又弃用了上述 API,使用了一条新的 API,如下:
public WebResourceResponse shouldInterceptRequest(WebView view, final WebResourceRequest request)
好吧,为了支持尽量多的版本,看来两个都需要实现了,发现一看就非常好用的 String url 变成了一个WebResourceRequest request。WebResourceRequest 这个东西是一个接口,并且是这样定义的:
public interface WebResourceRequest {
Uri getUrl();
boolean isForMainFrame();
boolean hasGesture();
String getMethod();
Map<String, String> getRequestHeaders();
}
在其中没有发现任何可以直接替换请求的方法。
然后搜索了一下 Android 代码中对他的引用,点我搜索。然后发现 private static class WebResourceRequestImpl implements WebResourceRequest 它的内部实现仅仅是一个单纯的实体。那这个东西要替换就非常好办了,三个方法都可以做:
*
反射
重新实现
实现
方案确定了,剩下的就简单了。直接上代码。
首先是往URL字符串加那个标志位的方法
public static String injectIsParams(String url) {
if (url != null && !url.contains("xxx=") {
if (url.contains("?")) {
return url + "&xxx=1";
} else {
return url + "?xxx=1";
}
} else {
return url;
}
}
然后要拦截所有请求了
webView.setWebViewClient(new WebViewClient() {
@SuppressLint("NewApi")
@Override
public WebResourceResponse shouldInterceptRequest(WebView view, final WebResourceRequest request) {
if (request != null && request.getUrl() != null) {
String scheme = request.getUrl().getScheme().trim();
if (scheme.equalsIgnoreCase("http") || scheme.equalsIgnoreCase("https")) {
return super.shouldInterceptRequest(view, new WebResourceRequest() {
@Override
public Uri getUrl() {
return Uri.parse(injectIsParams(request.getUrl().toString()));
}
@SuppressLint("NewApi")
@Override
public boolean isForMainFrame() {
return request.isForMainFrame();
}
@SuppressLint("NewApi")
@Override
public boolean hasGesture() {
return request.hasGesture();
}
@SuppressLint("NewApi")
@Override
public String getMethod() {
return request.getMethod();
}
@SuppressLint("NewApi")
@Override
public Map<String, String> getRequestHeaders() {
return request.getRequestHeaders();
}
});
}
}
return super.shouldInterceptRequest(view, request);
}
@Override
public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
if (!TextUtils.isEmpty(url) && Uri.parse(url).getScheme() != null) {
String scheme = Uri.parse(url).getScheme().trim();
if (scheme.equalsIgnoreCase("http") || scheme.equalsIgnoreCase("https")) {
return super.shouldInterceptRequest(view, injectIsParams(url));
}
}
return super.shouldInterceptRequest(view, url);
}
});
大功告成。
欢迎指出代码中的问题~~一起学习进步
注意: 注意保护 URL 的 Scheme,在代码 * 地过滤了 http 和 https。
引申
上边的 API 中发现还能有更多的玩法,比如:
替换 WebResourceResponse,构造一个自己的 WebResourceResponse。比如下列代码,用一个包里的本地文件替换掉要请求的网络图片。
WebResourceResponse response = null;
if (url.contains("logo")) {
try {
InputStream is = getAssets().open("test.png");
response = new WebResourceResponse("image/png", "UTF-8", is);
} catch (IOException e) {
e.printStackTrace();
}
}
return response;
在 API 21 (5.0) 以上的版本使用了 WebResourceRequest 接口,这个接口能修改发出请求的 Header
@Override
public Map<String, String> getRequestHeaders() {
return request.getRequestHeaders();
}
在 API 21 (5.0) 以上的版本中可以区分 GET 请求和 POST 请求,在某些情况下,需要区分 AJAX 的不同种类请求的时候可以用到。
来源:https://blog.csdn.net/cnzx219/article/details/46574073


猜你喜欢
- 如下所示:<span style="font-size:14px;">package com.imooc.r
- AndroidStudio使用过程中出现的异常异常信息: Gradle sync failed: Unable to start the d
- 1.基本介绍代码块又称为初始化块,属于类中的成员(类的一部分),类似于方法,讲逻辑语句封装在方法体中,用{}抱起来;但和方法不同,没有方法名
- using System; using System.IO; public class FileApp { &nbs
- 本文实例讲述了Android开发之ListView列表刷新和加载更多实现方法。分享给大家供大家参考。具体如下:上下拉实现刷新和加载更多的Li
- 背景在工作中,遇到这样的场景:有个es索引构建服务,需要从各个业务服务获取索引的信息,从而构建索引,业务服务都实现同一个接口&mda
- 1. pom.xml文件配置<?xml version="1.0" encoding="UTF-8&qu
- Java绘图中,显示文字的方法主要有三种:(1)drawString(String str,int x,int y):在指定的位置显示字符串
- 1 SeekBar简介SeekBar是进度条。我们使用进度条时,可以使用系统默认的进度条;也可以自定义进度条的图片和滑块图片等。2 Seek
- 上一次说了如何收集我们已经发布的应用程序的错误信息,方便我们调试完善程序。上次说的收集方法主要是把收集的信息通过Http的post请求把相关
- 先给大家展示下关于仿支付宝钱包首页中带有分割线的gridview,俗称九宫格 的效果图,怎么样是不是和你想象的一样啊。在你的预料之中就继续访
- 声明式事务很方便,尤其纯注解模式,仅仅几个注解就能控制事务了思考:这些注解都做了什么?好神奇!@EnableTransactionManag
- 需求:Android调用webView加载网页的时候,拦截某一个链接不执行此链接,执行指定跳转到其他activity页面。webview的s
- 参考文章Android中实时获取音量分贝值详解:https://www.jb51.net/article/64806.htmpublic c
- 目录Sonar概述一、 搭建sona服务二、idea配置三、 配置maven的setting.xml文件四、idea中 mvn sonar:
- 先看下利用wheelview实现滚动随机选择号码效果:直接上代码 首页就是dialog显示不在描述 主要看dialog代码package c
- 前言:项目是使用Java swing开发,可实现基础数据维护用户登录、系统首页酒店信息管理、主要模块是开房管理、退房管理、房间信息管理、顾客
- 1、使用步骤1)构建请求网址A、确定端点:每个GIS服务都有一个端点。例如,ArcGIS Server上Demographics文件夹下名为
- 前言最近在工作中遇到了这么一个需求:如何实现 Android 应用前后台切换的监听?下面来一起看看详细的介绍:iOS 内边是可以实现的,Ap
- 注解作用注解是JDK1.5版本开始引入的一个特性,用于对代码进行说明,可以对包、类、接口、字段、方法参数、局部变量等进行注解。它主要的作用有