我知道如何手动设置代理并在我的WebView中使用它。
设置 -> 无线网络 -> 移动网络 -> 接入点名称 -> telkila。现在输入代理服务器地址和端口号(将为80)。 WebView.enablePlatformNotifications();
但我能否从代码中设置代理设置? 这样我的用户就不必手动设置了吗?
谢谢
我知道如何手动设置代理并在我的WebView中使用它。
设置 -> 无线网络 -> 移动网络 -> 接入点名称 -> telkila。现在输入代理服务器地址和端口号(将为80)。 WebView.enablePlatformNotifications();
但我能否从代码中设置代理设置? 这样我的用户就不必手动设置了吗?
谢谢
我已经调整了这里提出的三个解决方案(并在其中一个失败时进行了修改),以生成一个适用于所有Android版本的单一简单setProxy方法。 我已经测试过从10到18的所有测试环境,它都可以正常工作。
更新于2014-04-04 最终我采用了下面评论中提供的解决方案,由nubela和xjy2061提供。现在,这适用于所有当前的Android版本,包括KitKat 4.4。如果您实现自己的Application子类,请将该类的名称作为可选的第四个参数。
更新于2015-01-15 KitKat方法中标记为可选的部分会因缺少辅助类而在Lollipop上抛出异常,但是没有那个部分它在KitKat和Lollipop上都能正常工作,因为WebView在两种情况下都基于Chromium。
public static boolean setProxy(WebView webview, String host, int port, String applicationClassName="android.app.Application") {
// 3.2 (HC) or lower
if (Build.VERSION.SDK_INT <= 13) {
return setProxyUpToHC(webview, host, port);
}
// ICS: 4.0
else 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);
}
}
/**
* 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 network
Class 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 = networkClass.getMethod("getInstance", Context.class);
if (getInstanceMethod == null) {
Log.e(LOG_TAG, "failed to get getInstance method");
}
network = getInstanceMethod.invoke(networkClass, new Object[]{webview.getContext()});
} 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 = networkClass
.getDeclaredField("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.net.http.RequestQueue");
proxyHostField = requestQueueClass
.getDeclaredField("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.net.ProxyProperties");
Method updateProxyInstance = jwcjb.getDeclaredMethod("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 = wvc.getDeclaredField("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.net.ProxyProperties");
Class pparams[] = new Class[3];
pparams[0] = String.class;
pparams[1] = int.class;
pparams[2] = String.class;
Constructor ppcont = ppclass.getConstructor(pparams);
updateProxyInstance.invoke(sJavaBridge, ppcont.newInstance(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;
}
}
/**
* 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 = wvcClass.getDeclaredMethod("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 = wvc.getDeclaredField("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.net.ProxyProperties");
Class pparams[] = new Class[3];
pparams[0] = String.class;
pparams[1] = int.class;
pparams[2] = String.class;
Constructor ppcont = ppclass.getConstructor(pparams);
Class jwcjb = Class.forName("android.webkit.JWebCoreJavaBridge");
Class params[] = new Class[1];
params[0] = Class.forName("android.net.ProxyProperties");
Method updateProxyInstance = jwcjb.getDeclaredMethod("updateProxy", params);
updateProxyInstance.invoke(sJavaBridge, ppcont.newInstance(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;
}
// from https://dev59.com/43nZa4cB1Zd3GeqPmSJf
@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 = webView.getContext().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 = applictionCls.getField("mLoadedApk");
loadedApkField.setAccessible(true);
Object loadedApk = loadedApkField.get(appContext);
Class loadedApkCls = Class.forName("android.app.LoadedApk");
Field receiversField = loadedApkCls.getDeclaredField("mReceivers");
receiversField.setAccessible(true);
ArrayMap receivers = (ArrayMap) receiversField.get(loadedApk);
for (Object receiverMap : receivers.values()) {
for (Object rec : ((ArrayMap) receiverMap).keySet()) {
Class clazz = rec.getClass();
if (clazz.getName().contains("ProxyChangeListener")) {
Method onReceiveMethod = clazz.getDeclaredMethod("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;
}
private static Object getFieldValueSafely(Field field, Object classInstance) throws IllegalArgumentException, IllegalAccessException {
boolean oldAccessibleValue = field.isAccessible();
field.setAccessible(true);
Object result = field.get(classInstance);
field.setAccessible(oldAccessibleValue);
return result;
}
没有合法的方法可以在程序中更改您的webview代理设置。但是可以使用Java反射从android.net.http.RequestQueue类更改mProxyHost值。它是私有值,并且没有为其提供设置器,因此反射似乎是唯一可能的变体。我在我的项目中使用了它,它起作用。这是我的方法示例:
private boolean setProxyHostField(HttpHost proxyServer) {
// Getting network
Class networkClass = null;
Object network = null;
try {
networkClass = Class.forName("android.webkit.Network");
Field networkField = networkClass.getDeclaredField("sNetwork");
network = getFieldValueSafely(networkField, null);
} catch (Exception ex) {
Log.e(ProxyManager.class.getName(), "error getting network");
return false;
}
if (network == null) {
Log.e(ProxyManager.class.getName(), "error getting network : null");
return false;
}
Object requestQueue = null;
try {
Field requestQueueField = networkClass
.getDeclaredField("mRequestQueue");
requestQueue = getFieldValueSafely(requestQueueField, network);
} catch (Exception ex) {
Log.e(ProxyManager.class.getName(), "error getting field value");
return false;
}
if (requestQueue == null) {
Log.e(ProxyManager.class.getName(), "Request queue is null");
return false;
}
Field proxyHostField = null;
try {
Class requestQueueClass = Class.forName("android.net.http.RequestQueue");
proxyHostField = requestQueueClass
.getDeclaredField("mProxyHost");
} catch (Exception ex) {
Log.e(ProxyManager.class.getName(), "error getting proxy host field");
return false;
}
synchronized (synchronizer) {
boolean temp = proxyHostField.isAccessible();
try {
proxyHostField.setAccessible(true);
proxyHostField.set(requestQueue, proxyServer);
} catch (Exception ex) {
Log.e(ProxyManager.class.getName(), "error setting proxy host");
} finally {
proxyHostField.setAccessible(temp);
}
}
return true;
}
private Object getFieldValueSafely(Field field, Object classInstance) throws IllegalArgumentException, IllegalAccessException {
boolean oldAccessibleValue = field.isAccessible();
field.setAccessible(true);
Object result = field.get(classInstance);
field.setAccessible(oldAccessibleValue);
return result;
}
我进行了许多测试,并且可以说,先前使用基于android.net.http.RequestQueue的覆盖方法可以完美地在Android 1.6到3.1上运行。
但是,在API上进行了代码重构,为了使其在Android 3.2和4.x上工作,这里是解决方案:
try
{
Class jwcjb = Class.forName("android.webkit.JWebCoreJavaBridge");
Class params[] = new Class[1];
params[0] = Class.forName("android.net.ProxyProperties");
Method updateProxyInstance = jwcjb.getDeclaredMethod("updateProxy", params);
Class wv = Class.forName("android.webkit.WebView");
Field mWebViewCoreField = wv.getDeclaredField("mWebViewCore");
Object mWebViewCoreFieldIntance = getFieldValueSafely(mWebViewCoreField, oauthPage);
Class wvc = Class.forName("android.webkit.WebViewCore");
Field mBrowserFrameField = wvc.getDeclaredField("mBrowserFrame");
Object mBrowserFrame = getFieldValueSafely(mBrowserFrameField, mWebViewCoreFieldIntance);
Class bf = Class.forName("android.webkit.BrowserFrame");
Field sJavaBridgeField = bf.getDeclaredField("sJavaBridge");
Object sJavaBridge = getFieldValueSafely(sJavaBridgeField, mBrowserFrame);
Class ppclass = Class.forName("android.net.ProxyProperties");
Class pparams[] = new Class[3];
pparams[0] = String.class;
pparams[1] = int.class;
pparams[2] = String.class;
Constructor ppcont = ppclass.getConstructor(pparams);
updateProxyInstance.invoke(sJavaBridge, ppcont.newInstance("my.proxy.com", 1234, null));
}
catch (Exception ex)
{
}
享受
当API >= 29时:
implementation 'androidx.webkit:webkit:1.4.0'
将以下内容添加到app/build.gradle文件中,然后
private fun setProxy(host: String, port: Int) {
if (WebViewFeature.isFeatureSupported(WebViewFeature.PROXY_OVERRIDE)) {
val proxyUrl = "${host}:${port}"
val proxyConfig: ProxyConfig = ProxyConfig.Builder()
.addProxyRule(proxyUrl)
.addDirect()//when proxy is not working, use direct connect, maybe?
.build()
ProxyController.getInstance().setProxyOverride(proxyConfig, object : Executor {
override fun execute(command: Runnable) {
}
}, Runnable { Log.w(TAG, "WebView proxy") })
} else {
// use the solution of other anwsers
}
}
Chromium在新版本中开始混淆类名(最新版本中ProxyChangeListener的类名似乎是“bMh”,并且可能会在将来的版本中更改。因此,Jimmy Dee的解决方案对于更新的版本将不再起作用,因为以下检查将始终失败:
if (clazz.getName().contains("ProxyChangeListener"))
// from https://dev59.com/43nZa4cB1Zd3GeqPmSJf
@SuppressLint("NewApi")
@SuppressWarnings("all")
private static boolean setProxyKKPlus(WebView webView, String host, int port, String applicationClassName, Context appContext) {
Log.d(LOG_TAG, "Setting proxy with >= 4.4 API.");
Context appContext = webView.getContext().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 = applictionCls.getField("mLoadedApk");
loadedApkField.setAccessible(true);
Object loadedApk = loadedApkField.get(appContext);
Class loadedApkCls = Class.forName("android.app.LoadedApk");
Field receiversField = loadedApkCls.getDeclaredField("mReceivers");
receiversField.setAccessible(true);
ArrayMap receivers = (ArrayMap) receiversField.get(loadedApk);
ArrayMap contextReceivers = (ArrayMap) receivers.get(appContext);
for (Object rec : contextReceivers.keySet()) {
Class clazz = rec.getClass();
Method onReceiveMethod = clazz.getDeclaredMethod("onReceive", Context.class, Intent.class);
Intent intent = new Intent(Proxy.PROXY_CHANGE_ACTION);
try {
onReceiveMethod.invoke(rec, appContext, intent);
} catch (Exception e) {
// oops, couldn't invoke this receiver
}
}
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;
}
如果社区中有人有更好的想法,那将非常有帮助。
Log.d(LOG_TAG, "Setting proxy with >= 4.4 API.");
Context appContext = webView.getContext().getApplicationContext();
System.setProperty("http.proxyHost", host);
System.setProperty("http.proxyPort", port + "");
System.setProperty("https.proxyHost", host);
System.setProperty("https.proxyPort", port + "");
try {
Field loadedApkField = appContext.getClass().getField("mLoadedApk");
loadedApkField.setAccessible(true);
Object loadedApk = loadedApkField.get(appContext);
Class loadedApkCls = Class.forName("android.app.LoadedApk");
Field receiversField = loadedApkCls.getDeclaredField("mReceivers");
receiversField.setAccessible(true);
ArrayMap receivers = (ArrayMap) receiversField.get(loadedApk);
for (Object receiverMap : receivers.values()) {
for (Object rec : ((ArrayMap) receiverMap).keySet()) {
Class clazz = rec.getClass();
if (clazz.getName().contains("ProxyChangeListener")) {
Method onReceiveMethod = clazz.getDeclaredMethod("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;
我移除了应用程序类名的使用。它在Android 7.1上运行良好。
/**
* Set Proxy from 3.0.x - to 3.1.x API.
* @param webview webview webview to apply proxy
* @param host host name of proxy server
* @param port port of proxy server
* @return true/false if success or not
*/
private static boolean setProxyOnlyHC30to31(WebView webview, String host, int port) {
try
{
Logger.d(ProxySettings.class, "Setting proxy from 3.0.x - 3.1.x API.");
Class jwcjb = Class.forName("android.webkit.JWebCoreJavaBridge");
Class params[] = new Class[1];
params[0] = Class.forName("java.lang.String");
Method updateProxyInstance = jwcjb.getDeclaredMethod("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 = wvc.getDeclaredField("mBrowserFrame");
Object mBrowserFrame = getFieldValueSafely(mBrowserFrameField, mWebViewCoreFieldInstance);
Class bf = Class.forName("android.webkit.BrowserFrame");
Field sJavaBridgeField = bf.getDeclaredField("sJavaBridge");
Object sJavaBridge = getFieldValueSafely(sJavaBridgeField, mBrowserFrame);
updateProxyInstance.invoke(sJavaBridge, "http://" + host + ":" + port);
Logger.d(ProxySettings.class, "Setting proxy from 3.0.x - 3.1.x API successful!");
return true;
}
catch (Exception ex)
{
if (Helper.DEBUG) Logger.e(ProxySettings.class, "failed to set HTTP proxy: " + ex);
return false;
}
}
/**
* Set Proxy for Android 4.1 and above.
*/
public static boolean setProxyICSPlus(WebView webview, String host, int port, String exclusionList) {
Log.d("", "Setting proxy with >= 4.1 API.");
try {
Class wvcClass = Class.forName("android.webkit.WebViewClassic");
Class wvParams[] = new Class[1];
wvParams[0] = Class.forName("android.webkit.WebView");
Method fromWebView = wvcClass.getDeclaredMethod("fromWebView", wvParams);
Object webViewClassic = fromWebView.invoke(null, webview);
Class wv = Class.forName("android.webkit.WebViewClassic");
Field mWebViewCoreField = wv.getDeclaredField("mWebViewCore");
Object mWebViewCoreFieldIntance = getFieldValueSafely(mWebViewCoreField, webViewClassic);
Class wvc = Class.forName("android.webkit.WebViewCore");
Field mBrowserFrameField = wvc.getDeclaredField("mBrowserFrame");
Object mBrowserFrame = getFieldValueSafely(mBrowserFrameField, mWebViewCoreFieldIntance);
Class bf = Class.forName("android.webkit.BrowserFrame");
Field sJavaBridgeField = bf.getDeclaredField("sJavaBridge");
Object sJavaBridge = getFieldValueSafely(sJavaBridgeField, mBrowserFrame);
Class ppclass = Class.forName("android.net.ProxyProperties");
Class pparams[] = new Class[3];
pparams[0] = String.class;
pparams[1] = int.class;
pparams[2] = String.class;
Constructor ppcont = ppclass.getConstructor(pparams);
Class jwcjb = Class.forName("android.webkit.JWebCoreJavaBridge");
Class params[] = new Class[1];
params[0] = Class.forName("android.net.ProxyProperties");
Method updateProxyInstance = jwcjb.getDeclaredMethod("updateProxy", params);
updateProxyInstance.invoke(sJavaBridge, ppcont.newInstance(host, port, exclusionList));
} catch (Exception ex) {
Log.e("","Setting proxy with >= 4.1 API failed with error: " + ex.getMessage());
return false;
}
Log.d("", "Setting proxy with >= 4.1 API successful!");
return true;
}
madeye的解决方案https://gist.github.com/madeye/2297083 伪代码:
android.webkit.Network.getInstance().mRequestQueue.mProxyHost=new HttpHost(host, port, "http") //sdk < 14
android.webkit.WebViewCore.sendStaticMessage(new android.net.ProxyProperties(...)) //sdk >= 14
比Birdy的答案(WebView android proxy)更好。伪代码:
android.webkit.Network.sNetwork.mRequestQueue.mProxyHost=new HttpHost(host, port, "http") //sdk < 14
比Guillaume13和MediumOne的答案更好(WebView android proxy)的伪代码:
android.webkit.JWebCoreJavaBridge.updateProxy(android.webkit.WebViewClassic.fromWebView(webview).mWebViewCore.mBrowserFrame.sJavaBridge, new android.net.ProxyProperties(...)) //sdk >= 14
但我不知道为什么只有在setProxy之前插入两行代码时代理才能成功:
webview1.loadUrl("http://0.0.0.0");
try {Thread.sleep(100);} catch (Exception e) {}
ProxySettings.setProxy(getApplicationContext(), "192.168.0.109", 8081);
webview1.loadUrl("http://www.google.com/index.php");