webview没有命中服务器套接字代理

时间:2013-06-28 16:07:00

标签: java android sockets webview serversocket

我使用以下代码片段设置了我的webview代理:

ProxySettings.setProxy(mContext, "http://127.0.0.1", PORT);

这是我的套接字服务器监听器

serverSocket = new ServerSocket(PORT);
thread = new Thread(runnable, this.getClass().getSimpleName());


public void startlistener() {
        listening = true;
        thread.start();

    }

private Runnable runnable = new Runnable() {

        @Override
        public void run() {
            while (listening) {
                try {
                    Socket accept = serverSocket.accept();

                    String data = getData(accept);

                    httpHandler.handleRequest(data);

                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }

        }
    };

我在String data = getData(accept)上放了一个断点;并且从未打过它

以下是取自https://gist.github.com/madeye/2297083

的代理类
public class ProxySettings {

    private static final String TAG = "GAEProxy.ProxySettings";

    static final int PROXY_CHANGED = 193;

    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;
    }

    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 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;
    }

    public static void resetProxy(Context ctx) throws Exception {
        Object requestQueueObject = getRequestQueue(ctx);
        if (requestQueueObject != null) {
            setDeclaredField(requestQueueObject, "mProxyHost", null);
        }
    }

    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);
    }

    /**
     * Override WebKit Proxy settings
     * 
     * @param ctx
     *            Android ApplicationContext
     * @param host
     * @param port
     * @return true if Proxy was successfully set
     */
    public static boolean setProxy(Context ctx, String host, int port) {
        boolean ret = false;
        setSystemProperties(host, port);

        try {
            if (Build.VERSION.SDK_INT < 14) {

                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;
                }

            } else {
                ret = setICSProxy(host, port);
            }
        } catch (Exception e) {
            Log.e(TAG, "error setting up webkit proxying", e);
        }
        return ret;
    }

    private static boolean setICSProxy(String host, int port)
            throws ClassNotFoundException, NoSuchMethodException,
            IllegalArgumentException, InstantiationException,
            IllegalAccessException, InvocationTargetException {
        Class webViewCoreClass = Class.forName("android.webkit.WebViewCore");
        Class proxyPropertiesClass = Class
                .forName("android.net.ProxyProperties");
        if (webViewCoreClass != null && proxyPropertiesClass != null) {
            Method m = webViewCoreClass.getDeclaredMethod("sendStaticMessage",
                    Integer.TYPE, Object.class);
            Constructor c = proxyPropertiesClass.getConstructor(String.class,
                    Integer.TYPE, String.class);
            m.setAccessible(true);
            c.setAccessible(true);
            Object properties = c.newInstance(host, port, null);
            m.invoke(null, PROXY_CHANGED, properties);
            return true;
        }
        return false;

    }

    private static void setSystemProperties(String host, int port) {

        System.setProperty("http.proxyHost", host);
        System.setProperty("http.proxyPort", port + "");

        System.setProperty("https.proxyHost", host);
        System.setProperty("https.proxyPort", port + "");

    }
}

我错过了什么吗?

ServerSocket运行在运行webview的同一个Android应用程序中,其目的是将所有http请求重定向到我的套接字服务器代理。

由于

编辑:我调试了代理代码并且失败并抛出此异常

07-01 15:44:02.894: E/GAEProxy.ProxySettings(11267): error setting up webkit proxying = java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()

当我调用setProxy时会发生这种情况。

有什么建议吗?

2 个答案:

答案 0 :(得分:3)

答案 1 :(得分:0)

如果您的应用程序未使用系统签名进行签名,则无法以编程方式设置代理。 How can you set the http proxy programatically?