Android Webview以编程方式设置代理Kitkat [英] Android Webview set proxy programmatically Kitkat

查看:284
本文介绍了Android Webview以编程方式设置代理Kitkat的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们如何才能在最新版本的Kitkat上以编程方式在Android Webview中设置代理?

How can we set proxy in Android webview programmatically on latest Kitkat release?

此SO链接 WebView android代理讨论的版本一直到SDK版本18.但是这些解决方案不再适用更改了基础Webkit的实现,并与Kitkat一起使用,并且现在使用的是铬.

This SO link WebView android proxy talks about version upto SDK version 18. But those solution no more works with Kitkat as underlying webkit implementation is changed and it uses chromium now.

推荐答案

这是我的解决方案:

public static void setKitKatWebViewProxy(Context appContext, String host, int port) {
    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("android.app.Application");
        Field loadedApkField = applictionCls.getDeclaredField("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);

                    /*********** optional, may be need in future *************/
                    final String CLASS_NAME = "android.net.ProxyProperties";
                    Class cls = Class.forName(CLASS_NAME);
                    Constructor constructor = cls.getConstructor(String.class, Integer.TYPE, String.class);
                    constructor.setAccessible(true);
                    Object proxyProperties = constructor.newInstance(host, port, null);
                    intent.putExtra("proxy", (Parcelable) proxyProperties);
                    /*********** optional, may be need in future *************/

                    onReceiveMethod.invoke(rec, appContext, intent);
                }
            }
        }
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    } catch (NoSuchFieldException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    } catch (IllegalArgumentException e) {
        e.printStackTrace();
    } catch (NoSuchMethodException e) {
        e.printStackTrace();
    } catch (InvocationTargetException e) {
        e.printStackTrace();
    } catch (InstantiationException e) {
        e.printStackTrace();
    }
}

希望它能为您提供帮助.

I hope it can help you.

注意:Context参数应该是Application上下文,如参数名称所示,您可以使用自己的实现的Application实例来扩展Application.

Note: The Context parameter should be an Application context as the parameter name showed, you could use your own implemented Application instance which extend Application.

这篇关于Android Webview以编程方式设置代理Kitkat的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆