zoukankan      html  css  js  c++  java
  • Android WebView代理设置方法(API10~21适用)

    最近碰到个需求需要在APP中加入代理,HttpClient的代理好解决,但是WebView碰到些问题,然后找到个API10~API21都通用的类,需要用的同学自己看吧,使用方法,直接调用类方法setProxy即可,applicationName可以设置为null。

      1 /**
      2  * Created by shengdong.huang on 2015/9/18.
      3  */
      4 public class ProxySettings {
      5 
      6     private static final String LOG_TAG = "halfman";
      7 
      8     private static final String APPLICATION_NAME = "android.app.Application";
      9 
     10 
     11     public static boolean setProxy(WebView webview, String host, int port, String applicationName) {
     12 
     13 
     14         // 3.2 (HC) or lower
     15         if (Build.VERSION.SDK_INT <= 13) {
     16             return setProxyUpToHC(webview, host, port);
     17         }
     18         // ICS: 4.0
     19         else if (Build.VERSION.SDK_INT <= 15) {
     20             return setProxyICS(webview, host, port);
     21         }
     22         // 4.1-4.3 (JB)
     23         else if (Build.VERSION.SDK_INT <= 18) {
     24             return setProxyJB(webview, host, port);
     25         }
     26         // 4.4 (KK) & 5.0 (Lollipop)
     27         else {
     28             return setProxyKKPlus(webview, host, port,
     29                     applicationName == null ? APPLICATION_NAME : applicationName);
     30         }
     31     }
     32 
     33     /**
     34      * Set Proxy for Android 3.2 and below.
     35      */
     36     @SuppressWarnings("all")
     37     private static boolean setProxyUpToHC(WebView webview, String host, int port) {
     38         Log.d(LOG_TAG, "Setting proxy with <= 3.2 API.");
     39 
     40         HttpHost proxyServer = new HttpHost(host, port);
     41         // Getting network
     42         Class networkClass = null;
     43         Object network = null;
     44         try {
     45             networkClass = Class.forName("android.webkit.Network");
     46             if (networkClass == null) {
     47                 Log.e(LOG_TAG, "failed to get class for android.webkit.Network");
     48                 return false;
     49             }
     50             Method getInstanceMethod = networkClass.getMethod("getInstance", Context.class);
     51             if (getInstanceMethod == null) {
     52                 Log.e(LOG_TAG, "failed to get getInstance method");
     53             }
     54             network = getInstanceMethod.invoke(networkClass, new Object[]{webview.getContext()});
     55         } catch (Exception ex) {
     56             Log.e(LOG_TAG, "error getting network: " + ex);
     57             return false;
     58         }
     59         if (network == null) {
     60             Log.e(LOG_TAG, "error getting network: network is null");
     61             return false;
     62         }
     63         Object requestQueue = null;
     64         try {
     65             Field requestQueueField = networkClass
     66                     .getDeclaredField("mRequestQueue");
     67             requestQueue = getFieldValueSafely(requestQueueField, network);
     68         } catch (Exception ex) {
     69             Log.e(LOG_TAG, "error getting field value");
     70             return false;
     71         }
     72         if (requestQueue == null) {
     73             Log.e(LOG_TAG, "Request queue is null");
     74             return false;
     75         }
     76         Field proxyHostField = null;
     77         try {
     78             Class requestQueueClass = Class.forName("android.net.http.RequestQueue");
     79             proxyHostField = requestQueueClass
     80                     .getDeclaredField("mProxyHost");
     81         } catch (Exception ex) {
     82             Log.e(LOG_TAG, "error getting proxy host field");
     83             return false;
     84         }
     85 
     86         boolean temp = proxyHostField.isAccessible();
     87         try {
     88             proxyHostField.setAccessible(true);
     89             proxyHostField.set(requestQueue, proxyServer);
     90         } catch (Exception ex) {
     91             Log.e(LOG_TAG, "error setting proxy host");
     92         } finally {
     93             proxyHostField.setAccessible(temp);
     94         }
     95 
     96         Log.d(LOG_TAG, "Setting proxy with <= 3.2 API successful!");
     97         return true;
     98     }
     99 
    100     @SuppressWarnings("all")
    101     private static boolean setProxyICS(WebView webview, String host, int port) {
    102         try
    103         {
    104             Log.d(LOG_TAG, "Setting proxy with 4.0 API.");
    105 
    106             Class jwcjb = Class.forName("android.webkit.JWebCoreJavaBridge");
    107             Class params[] = new Class[1];
    108             params[0] = Class.forName("android.net.ProxyProperties");
    109             Method updateProxyInstance = jwcjb.getDeclaredMethod("updateProxy", params);
    110 
    111             Class wv = Class.forName("android.webkit.WebView");
    112             Field mWebViewCoreField = wv.getDeclaredField("mWebViewCore");
    113             Object mWebViewCoreFieldInstance = getFieldValueSafely(mWebViewCoreField, webview);
    114 
    115             Class wvc = Class.forName("android.webkit.WebViewCore");
    116             Field mBrowserFrameField = wvc.getDeclaredField("mBrowserFrame");
    117             Object mBrowserFrame = getFieldValueSafely(mBrowserFrameField, mWebViewCoreFieldInstance);
    118 
    119             Class bf = Class.forName("android.webkit.BrowserFrame");
    120             Field sJavaBridgeField = bf.getDeclaredField("sJavaBridge");
    121             Object sJavaBridge = getFieldValueSafely(sJavaBridgeField, mBrowserFrame);
    122 
    123             Class ppclass = Class.forName("android.net.ProxyProperties");
    124             Class pparams[] = new Class[3];
    125             pparams[0] = String.class;
    126             pparams[1] = int.class;
    127             pparams[2] = String.class;
    128             Constructor ppcont = ppclass.getConstructor(pparams);
    129 
    130             updateProxyInstance.invoke(sJavaBridge, ppcont.newInstance(host, port, null));
    131 
    132             Log.d(LOG_TAG, "Setting proxy with 4.0 API successful!");
    133             return true;
    134         }
    135         catch (Exception ex)
    136         {
    137             Log.e(LOG_TAG, "failed to set HTTP proxy: " + ex);
    138             return false;
    139         }
    140     }
    141 
    142     /**
    143      * Set Proxy for Android 4.1 - 4.3.
    144      */
    145     @SuppressWarnings("all")
    146     private static boolean setProxyJB(WebView webview, String host, int port) {
    147         Log.d(LOG_TAG, "Setting proxy with 4.1 - 4.3 API.");
    148 
    149         try {
    150             Class wvcClass = Class.forName("android.webkit.WebViewClassic");
    151             Class wvParams[] = new Class[1];
    152             wvParams[0] = Class.forName("android.webkit.WebView");
    153             Method fromWebView = wvcClass.getDeclaredMethod("fromWebView", wvParams);
    154             Object webViewClassic = fromWebView.invoke(null, webview);
    155 
    156             Class wv = Class.forName("android.webkit.WebViewClassic");
    157             Field mWebViewCoreField = wv.getDeclaredField("mWebViewCore");
    158             Object mWebViewCoreFieldInstance = getFieldValueSafely(mWebViewCoreField, webViewClassic);
    159 
    160             Class wvc = Class.forName("android.webkit.WebViewCore");
    161             Field mBrowserFrameField = wvc.getDeclaredField("mBrowserFrame");
    162             Object mBrowserFrame = getFieldValueSafely(mBrowserFrameField, mWebViewCoreFieldInstance);
    163 
    164             Class bf = Class.forName("android.webkit.BrowserFrame");
    165             Field sJavaBridgeField = bf.getDeclaredField("sJavaBridge");
    166             Object sJavaBridge = getFieldValueSafely(sJavaBridgeField, mBrowserFrame);
    167 
    168             Class ppclass = Class.forName("android.net.ProxyProperties");
    169             Class pparams[] = new Class[3];
    170             pparams[0] = String.class;
    171             pparams[1] = int.class;
    172             pparams[2] = String.class;
    173             Constructor ppcont = ppclass.getConstructor(pparams);
    174 
    175             Class jwcjb = Class.forName("android.webkit.JWebCoreJavaBridge");
    176             Class params[] = new Class[1];
    177             params[0] = Class.forName("android.net.ProxyProperties");
    178             Method updateProxyInstance = jwcjb.getDeclaredMethod("updateProxy", params);
    179 
    180             updateProxyInstance.invoke(sJavaBridge, ppcont.newInstance(host, port, null));
    181         } catch (Exception ex) {
    182             Log.e(LOG_TAG,"Setting proxy with >= 4.1 API failed with error: " + ex.getMessage());
    183             return false;
    184         }
    185 
    186         Log.d(LOG_TAG, "Setting proxy with 4.1 - 4.3 API successful!");
    187         return true;
    188     }
    189     
    190     @SuppressWarnings("all")
    191     private static boolean setProxyKKPlus(WebView webView, String host, int port, String applicationClassName) {
    192         Log.d(LOG_TAG, "Setting proxy with >= 4.4 API.");
    193 
    194         Context appContext = webView.getContext().getApplicationContext();
    195         System.setProperty("http.proxyHost", host);
    196         System.setProperty("http.proxyPort", port + "");
    197         System.setProperty("https.proxyHost", host);
    198         System.setProperty("https.proxyPort", port + "");
    199         try {
    200             Class applictionCls = Class.forName(applicationClassName);
    201             Field loadedApkField = applictionCls.getField("mLoadedApk");
    202             loadedApkField.setAccessible(true);
    203             Object loadedApk = loadedApkField.get(appContext);
    204             Class loadedApkCls = Class.forName("android.app.LoadedApk");
    205             Field receiversField = loadedApkCls.getDeclaredField("mReceivers");
    206             receiversField.setAccessible(true);
    207             ArrayMap receivers = (ArrayMap) receiversField.get(loadedApk);
    208             for (Object receiverMap : receivers.values()) {
    209                 for (Object rec : ((ArrayMap) receiverMap).keySet()) {
    210                     Class clazz = rec.getClass();
    211                     if (clazz.getName().contains("ProxyChangeListener")) {
    212                         Method onReceiveMethod = clazz.getDeclaredMethod("onReceive", Context.class, Intent.class);
    213                         Intent intent = new Intent(Proxy.PROXY_CHANGE_ACTION);
    214 
    215                         onReceiveMethod.invoke(rec, appContext, intent);
    216                     }
    217                 }
    218             }
    219 
    220             Log.d(LOG_TAG, "Setting proxy with >= 4.4 API successful!");
    221             return true;
    222         } catch (ClassNotFoundException e) {
    223             StringWriter sw = new StringWriter();
    224             e.printStackTrace(new PrintWriter(sw));
    225             String exceptionAsString = sw.toString();
    226             Log.v(LOG_TAG, e.getMessage());
    227             Log.v(LOG_TAG, exceptionAsString);
    228         } catch (NoSuchFieldException e) {
    229             StringWriter sw = new StringWriter();
    230             e.printStackTrace(new PrintWriter(sw));
    231             String exceptionAsString = sw.toString();
    232             Log.v(LOG_TAG, e.getMessage());
    233             Log.v(LOG_TAG, exceptionAsString);
    234         } catch (IllegalAccessException e) {
    235             StringWriter sw = new StringWriter();
    236             e.printStackTrace(new PrintWriter(sw));
    237             String exceptionAsString = sw.toString();
    238             Log.v(LOG_TAG, e.getMessage());
    239             Log.v(LOG_TAG, exceptionAsString);
    240         } catch (IllegalArgumentException e) {
    241             StringWriter sw = new StringWriter();
    242             e.printStackTrace(new PrintWriter(sw));
    243             String exceptionAsString = sw.toString();
    244             Log.v(LOG_TAG, e.getMessage());
    245             Log.v(LOG_TAG, exceptionAsString);
    246         } catch (NoSuchMethodException e) {
    247             StringWriter sw = new StringWriter();
    248             e.printStackTrace(new PrintWriter(sw));
    249             String exceptionAsString = sw.toString();
    250             Log.v(LOG_TAG, e.getMessage());
    251             Log.v(LOG_TAG, exceptionAsString);
    252         } catch (InvocationTargetException e) {
    253             StringWriter sw = new StringWriter();
    254             e.printStackTrace(new PrintWriter(sw));
    255             String exceptionAsString = sw.toString();
    256             Log.v(LOG_TAG, e.getMessage());
    257             Log.v(LOG_TAG, exceptionAsString);
    258         }
    259         return false;
    260     }
    261 
    262     private static Object getFieldValueSafely(Field field, Object classInstance) throws IllegalArgumentException, IllegalAccessException {
    263         boolean oldAccessibleValue = field.isAccessible();
    264         field.setAccessible(true);
    265         Object result = field.get(classInstance);
    266         field.setAccessible(oldAccessibleValue);
    267         return result;
    268     }
    269 }

    就是这些,祝码运昌隆~~

  • 相关阅读:
    linux基础——虚拟机的创建及安装操作系统
    并发编程之多进程
    操作系统与进程(理论知识点)
    粘包
    socket-网络编程
    网络编程1
    网络编程
    异常
    元类
    反射与内置方法
  • 原文地址:https://www.cnblogs.com/halfmanhuang/p/4818671.html
Copyright © 2011-2022 走看看