在android1.6之前的api中有有直接的方法来对webview设置代码,但是在之后的API中去掉了。所以只能寻求别的方法来设置代码。
下面代码是用反射原理来对webview设置代理:
public static boolean setProxy(Context ctx, String host, int port) {
boolean ret = false;
try {
Log.d("WebViewProxySettings", "setProxy defaulthost="+host+"port="+port);
Object requestQueueObject = getRequestQueue(ctx);
if (requestQueueObject != null) {
//Create Proxy config object and set it into request Q
HttpHost httpHost = new HttpHost(host, port, "http");
setDeclaredField(requestQueueObject, "mProxyHost", httpHost);
ret = true;
}
} catch (Exception e) {
e.printStackTrace();
}
return ret;
}
public static String getProxyHostname(Context ctx){
String res = null;
try {
Object requestQueueObject = getRequestQueue(ctx);
if (requestQueueObject != null) {
Object fild = getDeclaredField(requestQueueObject,"mProxyHost");
if(fild!=null){
HttpHost host = (HttpHost)fild;
res = host.getHostName();
}
}
} catch (Exception e) {
e.printStackTrace();
}
return res;
}
public static void cancelProxy(Context ctx){
try {
Object requestQueueObject = getRequestQueue(ctx);
if (requestQueueObject != null) {
setDeclaredField(requestQueueObject, "mProxyHost", null);
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static Object getRequestQueue(Context ctx) throws Exception {
Object ret = null;
Class networkClass = Class.forName("android.webkit.Network");
if (networkClass != null) {
Object networkObj = invokeMethod(networkClass, "getInstance", new Object[]{ctx}, Context.class);
if (networkObj != null) {
ret = getDeclaredField(networkObj, "mRequestQueue");
}
}
return ret;
}
private static Object getDeclaredField(Object obj, String name)
throws SecurityException, NoSuchFieldException,
IllegalArgumentException, IllegalAccessException {
Field f = obj.getClass().getDeclaredField(name);
f.setAccessible(true);
Object out = f.get(obj);
//System.out.println(obj.getClass().getName() + "." + name + " = "+ out);
return out;
}
private static void setDeclaredField(Object obj, String name, Object value)
throws SecurityException, NoSuchFieldException,
IllegalArgumentException, IllegalAccessException {
Field f = obj.getClass().getDeclaredField(name);
f.setAccessible(true);
f.set(obj, value);
}
private static Object invokeMethod(Object object, String methodName, Object[] params, Class... types) throws Exception {
Object out = null;
Class c = object instanceof Class ? (Class) object : object.getClass();
if (types != null) {
Method method = c.getMethod(methodName, types);
out = method.invoke(object, params);
} else {
Method method = c.getMethod(methodName);
out = method.invoke(object);
}
//System.out.println(object.getClass().getName() + "." + methodName + "() = "+ out);
return out;
}