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

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

问题描述

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

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

此 SO 链接 WebView android 代理 讨论了 SDK 版本 18 之前的版本.但这些解决方案不再适用与 Kitkat 一起使用,因为底层 webkit 实现已更改,现在使用铬.

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

希望能帮到你.

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

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天全站免登陆