3

我已经使用下面的这段代码设置了我的 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 时。

有什么建议么?

4

2 回答 2

3

错误告诉您:无法在未调用 Looper.prepare() 的线程内创建处理程序

您需要在实现 Looper 的 Thread 中执行代码。

无法在未调用 Looper.prepare() 的线程内创建处理程序

无法在 AsyncTask 中为 ProgressDialog 调用 Looper.prepare() 的线程内创建处理程序

无法在未调用 Looper.prepare() 的线程内创建处理程序

于 2013-07-06T15:54:45.010 回答
0

如果您的应用程序未使用系统签名进行签名,则无法以编程方式设置代理。如何以编程方式设置 http 代理?

于 2013-07-01T11:35:30.990 回答