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 }

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

原文地址:https://www.cnblogs.com/halfmanhuang/p/4818671.html