Android中给webview设置代理

阅读: 评论:0

Android中给webview设置代理

Android中给webview设置代理

亲测:支持安卓9.0以下都可以正常使用

webview在loadUrl之前,调用如下函数,设置代理:

public static boolean setProxy(WebView webview, String host, int port, String applicationClassName)

在关闭、或者销毁webview之前,调用如下函数,取消代理:

public static boolean revertBackProxy(WebView webview, String applicationClassName)

 

完整代码如下(此处我用的X5的webview,原生webview也是支持):

package Sdk.util;import android.annotation.SuppressLint;
t.Context;
t.Intent;
import android.Proxy;
import android.os.Build;
TextUtils;
import android.util.ArrayMap;
import android.util.Log;t.smtt.sdk.WebView;import org.apache.http.HttpHost;import java.io.PrintWriter;
import java.io.StringWriter;
import flect.Constructor;
import flect.Field;
import flect.InvocationTargetException;
import flect.Method;
import java.util.Properties;/*** 给webview设置代理的方式* <p>* Created by hwk on 2019/1/28.*/
public class WebviewSettingProxy {private static final String LOG_TAG = "WebviewSettingProxy";/*** 给webview设置代理** @param webview* @param host                 ip* @param port                 端口* @param applicationClassName 注意这里applicationClassName 传递的是 application 的类名* @return*/public static boolean setProxy(WebView webview, String host, int port, String applicationClassName) {// 3.2 (HC) or lowerif (Build.VERSION.SDK_INT <= 13) {return setProxyUpToHC(webview, host, port);}// ICS: 4.0else if (Build.VERSION.SDK_INT <= 15) {return setProxyICS(webview, host, port);}// 4.1-4.3 (JB)else if (Build.VERSION.SDK_INT <= 18) {return setProxyJB(webview, host, port);}// 4.4 (KK) & 5.0 (Lollipop)else {return setProxyKKPlus(webview, host, port, applicationClassName);}}/*** 给webview取消代理** @param webview* @param applicationClassName 注意这里applicationClassName 传递的是 application 的类名* @return*/public static boolean revertBackProxy(WebView webview, String applicationClassName) {if (webview == null || TextUtils.isEmpty(applicationClassName)) {return true;}// 3.2 (HC) or lowerif (Build.VERSION.SDK_INT <= 13) {return true;}// ICS: 4.0else if (Build.VERSION.SDK_INT <= 15) {return revertProxyICS(webview);}// 4.1-4.3 (JB)else if (Build.VERSION.SDK_INT <= 18) {return revertProxyJB(webview);}// 4.4 (KK) & 5.0 (Lollipop)else {return revertProxyKKPlus(webview, applicationClassName);}}/*** Set Proxy for Android 3.2 and below.*/@SuppressWarnings("all")private static boolean setProxyUpToHC(WebView webview, String host, int port) {Log.d(LOG_TAG, "Setting proxy with <= 3.2 API.");HttpHost proxyServer = new HttpHost(host, port);// Getting networkClass networkClass = null;Object network = null;try {networkClass = Class.forName("android.webkit.Network");if (networkClass == null) {Log.e(LOG_TAG, "failed to get class for android.webkit.Network");return false;}Method getInstanceMethod = Method("getInstance", Context.class);if (getInstanceMethod == null) {Log.e(LOG_TAG, "failed to get getInstance method");}network = getInstanceMethod.invoke(networkClass, new Object[]{Context()});} catch (Exception ex) {Log.e(LOG_TAG, "error getting network: " + ex);return false;}if (network == null) {Log.e(LOG_TAG, "error getting network: network is null");return false;}Object requestQueue = null;try {Field requestQueueField = DeclaredField("mRequestQueue");requestQueue = getFieldValueSafely(requestQueueField, network);} catch (Exception ex) {Log.e(LOG_TAG, "error getting field value");return false;}if (requestQueue == null) {Log.e(LOG_TAG, "Request queue is null");return false;}Field proxyHostField = null;try {Class requestQueueClass = Class.forName("android.http.RequestQueue");proxyHostField = DeclaredField("mProxyHost");} catch (Exception ex) {Log.e(LOG_TAG, "error getting proxy host field");return false;}boolean temp = proxyHostField.isAccessible();try {proxyHostField.setAccessible(true);proxyHostField.set(requestQueue, proxyServer);} catch (Exception ex) {Log.e(LOG_TAG, "error setting proxy host");} finally {proxyHostField.setAccessible(temp);}Log.d(LOG_TAG, "Setting proxy with <= 3.2 API successful!");return true;}@SuppressWarnings("all")private static boolean setProxyICS(WebView webview, String host, int port) {try {Log.d(LOG_TAG, "Setting proxy with 4.0 API.");Class jwcjb = Class.forName("android.webkit.JWebCoreJavaBridge");Class params[] = new Class[1];params[0] = Class.forName("android.ProxyProperties");Method updateProxyInstance = DeclaredMethod("updateProxy", params);Class wv = Class.forName("android.webkit.WebView");Field mWebViewCoreField = wv.getDeclaredField("mWebViewCore");Object mWebViewCoreFieldInstance = getFieldValueSafely(mWebViewCoreField, webview);Class wvc = Class.forName("android.webkit.WebViewCore");Field mBrowserFrameField = DeclaredField("mBrowserFrame");Object mBrowserFrame = getFieldValueSafely(mBrowserFrameField, mWebViewCoreFieldInstance);Class bf = Class.forName("android.webkit.BrowserFrame");Field sJavaBridgeField = bf.getDeclaredField("sJavaBridge");Object sJavaBridge = getFieldValueSafely(sJavaBridgeField, mBrowserFrame);Class ppclass = Class.forName("android.ProxyProperties");Class pparams[] = new Class[3];pparams[0] = String.class;pparams[1] = int.class;pparams[2] = String.class;Constructor ppcont = Constructor(pparams);updateProxyInstance.invoke(sJavaBridge, wInstance(host, port, null));Log.d(LOG_TAG, "Setting proxy with 4.0 API successful!");return true;} catch (Exception ex) {Log.e(LOG_TAG, "failed to set HTTP proxy: " + ex);return false;}}private static boolean revertProxyICS(WebView webview) {try {Log.d(LOG_TAG, "Setting proxy with 4.0 API.");Class jwcjb = Class.forName("android.webkit.JWebCoreJavaBridge");Class params[] = new Class[1];params[0] = Class.forName("android.ProxyProperties");Method updateProxyInstance = DeclaredMethod("updateProxy", params);Class wv = Class.forName("android.webkit.WebView");Field mWebViewCoreField = wv.getDeclaredField("mWebViewCore");Object mWebViewCoreFieldInstance = getFieldValueSafely(mWebViewCoreField, webview);Class wvc = Class.forName("android.webkit.WebViewCore");Field mBrowserFrameField = DeclaredField("mBrowserFrame");Object mBrowserFrame = getFieldValueSafely(mBrowserFrameField, mWebViewCoreFieldInstance);Class bf = Class.forName("android.webkit.BrowserFrame");Field sJavaBridgeField = bf.getDeclaredField("sJavaBridge");Object sJavaBridge = getFieldValueSafely(sJavaBridgeField, mBrowserFrame);Class ppclass = Class.forName("android.ProxyProperties");Class pparams[] = new Class[3];pparams[0] = String.class;pparams[1] = int.class;pparams[2] = String.class;Constructor ppcont = Constructor(pparams);Object o = null;updateProxyInstance.invoke(sJavaBridge, o);Log.d(LOG_TAG, "Setting proxy with 4.0 API successful!");return true;} catch (Exception ex) {Log.e(LOG_TAG, "failed to set HTTP proxy: " + ex);return false;}}/*** Set Proxy for Android 4.1 - 4.3.*/@SuppressWarnings("all")private static boolean setProxyJB(WebView webview, String host, int port) {Log.d(LOG_TAG, "Setting proxy with 4.1 - 4.3 API.");try {Class wvcClass = Class.forName("android.webkit.WebViewClassic");Class wvParams[] = new Class[1];wvParams[0] = Class.forName("android.webkit.WebView");Method fromWebView = DeclaredMethod("fromWebView", wvParams);Object webViewClassic = fromWebView.invoke(null, webview);Class wv = Class.forName("android.webkit.WebViewClassic");Field mWebViewCoreField = wv.getDeclaredField("mWebViewCore");Object mWebViewCoreFieldInstance = getFieldValueSafely(mWebViewCoreField, webViewClassic);Class wvc = Class.forName("android.webkit.WebViewCore");Field mBrowserFrameField = DeclaredField("mBrowserFrame");Object mBrowserFrame = getFieldValueSafely(mBrowserFrameField, mWebViewCoreFieldInstance);Class bf = Class.forName("android.webkit.BrowserFrame");Field sJavaBridgeField = bf.getDeclaredField("sJavaBridge");Object sJavaBridge = getFieldValueSafely(sJavaBridgeField, mBrowserFrame);Class ppclass = Class.forName("android.ProxyProperties");Class pparams[] = new Class[3];pparams[0] = String.class;pparams[1] = int.class;pparams[2] = String.class;Constructor ppcont = Constructor(pparams);Class jwcjb = Class.forName("android.webkit.JWebCoreJavaBridge");Class params[] = new Class[1];params[0] = Class.forName("android.ProxyProperties");Method updateProxyInstance = DeclaredMethod("updateProxy", params);updateProxyInstance.invoke(sJavaBridge, wInstance(host, port, null));} catch (Exception ex) {Log.e(LOG_TAG, "Setting proxy with >= 4.1 API failed with error: " + ex.getMessage());return false;}Log.d(LOG_TAG, "Setting proxy with 4.1 - 4.3 API successful!");return true;}private static boolean revertProxyJB(WebView webview) {Log.d(LOG_TAG, "revert proxy with 4.1 - 4.3 API.");try {Class wvcClass = Class.forName("android.webkit.WebViewClassic");Class wvParams[] = new Class[1];wvParams[0] = Class.forName("android.webkit.WebView");Method fromWebView = DeclaredMethod("fromWebView", wvParams);Object webViewClassic = fromWebView.invoke(null, webview);Class wv = Class.forName("android.webkit.WebViewClassic");Field mWebViewCoreField = wv.getDeclaredField("mWebViewCore");Object mWebViewCoreFieldInstance = getFieldValueSafely(mWebViewCoreField, webViewClassic);Class wvc = Class.forName("android.webkit.WebViewCore");Field mBrowserFrameField = DeclaredField("mBrowserFrame");Object mBrowserFrame = getFieldValueSafely(mBrowserFrameField, mWebViewCoreFieldInstance);Class bf = Class.forName("android.webkit.BrowserFrame");Field sJavaBridgeField = bf.getDeclaredField("sJavaBridge");Object sJavaBridge = getFieldValueSafely(sJavaBridgeField, mBrowserFrame);Class ppclass = Class.forName("android.ProxyProperties");Class pparams[] = new Class[3];pparams[0] = String.class;pparams[1] = int.class;pparams[2] = String.class;Constructor ppcont = Constructor(pparams);Class jwcjb = Class.forName("android.webkit.JWebCoreJavaBridge");Class params[] = new Class[1];params[0] = Class.forName("android.ProxyProperties");Method updateProxyInstance = DeclaredMethod("updateProxy", params);Object o = null;updateProxyInstance.invoke(sJavaBridge, o);} catch (Exception ex) {Log.e(LOG_TAG, "Setting proxy with >= 4.1 API failed with error: " + ex.getMessage());return false;}Log.d(LOG_TAG, "revert proxy with 4.1 - 4.3 API successful!");return true;}// from @SuppressLint("NewApi")@SuppressWarnings("all")private static boolean setProxyKKPlus(WebView webView, String host, int port, String applicationClassName) {Log.d(LOG_TAG, "Setting proxy with >= 4.4 API.");Context appContext = Context().getApplicationContext();System.setProperty("http.proxyHost", host);System.setProperty("http.proxyPort", port + "");System.setProperty("https.proxyHost", host);System.setProperty("https.proxyPort", port + "");try {Class applictionCls = Class.forName(applicationClassName);Field loadedApkField = Field("mLoadedApk");loadedApkField.setAccessible(true);Object loadedApk = (appContext);Class loadedApkCls = Class.forName("android.app.LoadedApk");Field receiversField = DeclaredField("mReceivers");receiversField.setAccessible(true);ArrayMap receivers = (ArrayMap) (loadedApk);for (Object receiverMap : receivers.values()) {for (Object rec : ((ArrayMap) receiverMap).keySet()) {Class clazz = Class();if (Name().contains("ProxyChangeListener")) {Method onReceiveMethod = DeclaredMethod("onReceive", Context.class, Intent.class);Intent intent = new Intent(Proxy.PROXY_CHANGE_ACTION);onReceiveMethod.invoke(rec, appContext, intent);}}}Log.d(LOG_TAG, "Setting proxy with >= 4.4 API successful!");return true;} catch (ClassNotFoundException e) {StringWriter sw = new StringWriter();e.printStackTrace(new PrintWriter(sw));String exceptionAsString = sw.toString();Log.v(LOG_TAG, e.getMessage());Log.v(LOG_TAG, exceptionAsString);} catch (NoSuchFieldException e) {StringWriter sw = new StringWriter();e.printStackTrace(new PrintWriter(sw));String exceptionAsString = sw.toString();Log.v(LOG_TAG, e.getMessage());Log.v(LOG_TAG, exceptionAsString);} catch (IllegalAccessException e) {StringWriter sw = new StringWriter();e.printStackTrace(new PrintWriter(sw));String exceptionAsString = sw.toString();Log.v(LOG_TAG, e.getMessage());Log.v(LOG_TAG, exceptionAsString);} catch (IllegalArgumentException e) {StringWriter sw = new StringWriter();e.printStackTrace(new PrintWriter(sw));String exceptionAsString = sw.toString();Log.v(LOG_TAG, e.getMessage());Log.v(LOG_TAG, exceptionAsString);} catch (NoSuchMethodException e) {StringWriter sw = new StringWriter();e.printStackTrace(new PrintWriter(sw));String exceptionAsString = sw.toString();Log.v(LOG_TAG, e.getMessage());Log.v(LOG_TAG, exceptionAsString);} catch (InvocationTargetException e) {StringWriter sw = new StringWriter();e.printStackTrace(new PrintWriter(sw));String exceptionAsString = sw.toString();Log.v(LOG_TAG, e.getMessage());Log.v(LOG_TAG, exceptionAsString);}return false;}@SuppressLint("NewApi")@SuppressWarnings("all")private static boolean revertProxyKKPlus(WebView webView, String applicationClassName) {Context appContext = Context().getApplicationContext();Properties properties = Properties();ve("http.proxyHost");ve("http.proxyPort");ve("https.proxyHost");ve("https.proxyPort");try {Class applictionCls = Class.forName(applicationClassName);Field loadedApkField = Field("mLoadedApk");loadedApkField.setAccessible(true);Object loadedApk = (appContext);Class loadedApkCls = Class.forName("android.app.LoadedApk");Field receiversField = DeclaredField("mReceivers");receiversField.setAccessible(true);ArrayMap receivers = (ArrayMap) (loadedApk);for (Object receiverMap : receivers.values()) {for (Object rec : ((ArrayMap) receiverMap).keySet()) {Class clazz = Class();if (Name().contains("ProxyChangeListener")) {Method onReceiveMethod = DeclaredMethod("onReceive", Context.class, Intent.class);Intent intent = new Intent(Proxy.PROXY_CHANGE_ACTION);
//                        intent.putExtra("proxy", null);onReceiveMethod.invoke(rec, appContext, intent);}}}Log.d(LOG_TAG, "Revert proxy with >= 4.4 API successful!");return true;} catch (ClassNotFoundException e) {StringWriter sw = new StringWriter();e.printStackTrace(new PrintWriter(sw));String exceptionAsString = sw.toString();Log.v(LOG_TAG, e.getMessage());Log.v(LOG_TAG, exceptionAsString);} catch (NoSuchFieldException e) {StringWriter sw = new StringWriter();e.printStackTrace(new PrintWriter(sw));String exceptionAsString = sw.toString();Log.v(LOG_TAG, e.getMessage());Log.v(LOG_TAG, exceptionAsString);} catch (IllegalAccessException e) {StringWriter sw = new StringWriter();e.printStackTrace(new PrintWriter(sw));String exceptionAsString = sw.toString();Log.v(LOG_TAG, e.getMessage());Log.v(LOG_TAG, exceptionAsString);} catch (IllegalArgumentException e) {StringWriter sw = new StringWriter();e.printStackTrace(new PrintWriter(sw));String exceptionAsString = sw.toString();Log.v(LOG_TAG, e.getMessage());Log.v(LOG_TAG, exceptionAsString);} catch (NoSuchMethodException e) {StringWriter sw = new StringWriter();e.printStackTrace(new PrintWriter(sw));String exceptionAsString = sw.toString();Log.v(LOG_TAG, e.getMessage());Log.v(LOG_TAG, exceptionAsString);} catch (InvocationTargetException e) {StringWriter sw = new StringWriter();e.printStackTrace(new PrintWriter(sw));String exceptionAsString = sw.toString();Log.v(LOG_TAG, e.getMessage());Log.v(LOG_TAG, exceptionAsString);}return false;}private static Object getFieldValueSafely(Field field, Object classInstance) throws IllegalArgumentException, IllegalAccessException {boolean oldAccessibleValue = field.isAccessible();field.setAccessible(true);Object result = (classInstance);field.setAccessible(oldAccessibleValue);return result;}
}

 

本文发布于:2024-02-04 19:42:06,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/170715017458932.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:Android   webview
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23