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 }

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

  • 相关阅读:
    LeetCode 769. Max Chunks To Make Sorted
    LeetCode 845. Longest Mountain in Array
    LeetCode 1059. All Paths from Source Lead to Destination
    1129. Shortest Path with Alternating Colors
    LeetCode 785. Is Graph Bipartite?
    LeetCode 802. Find Eventual Safe States
    LeetCode 1043. Partition Array for Maximum Sum
    LeetCode 841. Keys and Rooms
    LeetCode 1061. Lexicographically Smallest Equivalent String
    LeetCode 1102. Path With Maximum Minimum Value
  • 原文地址:https://www.cnblogs.com/halfmanhuang/p/4818671.html
Copyright © 2011-2022 走看看