Importing a newer Apache HttpClient jar in Android
我正在尝试从我的Android客户端发送HTTP / HTTPS发布请求。
题
为什么我的代码失败?
至今
我创建了一个apache class / HttpClient调用。 一切正常:
1 | HttpClient httpClient = new DefaultHttpClient(); |
我已经阅读过此方法已被弃用,因此我已切换到新的推荐方法:
1 | HttpClient httpClient = HttpClientBuilder.create().build(); |
Eclipse没有此类,因此我必须下载Apache HttpClient 4.3.3。 我通过将其复制到
错误信息
1 2 | 06-05 02:15:26.946: W/dalvikvm(29587): Link of class 'Lorg/apache/http/impl/conn/PoolingHttpClientConnectionManager;' failed 06-05 02:15:26.946: E/dalvikvm(29587): Could not find class 'org.apache.http.impl.conn.PoolingHttpClientConnectionManager', referenced from method org.apache.http.impl.client.HttpClientBuilder.build |
最新代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | static private String insertJson(String json,String url){ HttpClient httpClient = HttpClientBuilder.create().build(); String responseString =""; try { HttpPost request = new HttpPost(url); StringEntity params =new StringEntity(json,"UTF-8"); request.addHeader("content-type","application/json"); request.setEntity(params); HttpResponse response = httpClient.execute(request); HttpEntity entity = response.getEntity(); responseString = EntityUtils.toString(entity,"UTF-8"); }catch (Exception ex) { ex.printStackTrace(); // handle exception here } finally { httpClient.getConnectionManager().shutdown(); } return responseString; } |
问题在于,Android已经包含了Apache HttpClient的旧版本(目前尚不清楚哪个版本,但大约是4.0beta2)。
当您将新版本的jar添加为应用程序的库时,在加载APK时会忽略重复的类。由于HttpClient中的某些新类依赖于对这些其他类所做的修改,因此dalvik会尽其所能(例如,删除引用和&c),但是除非有条件地使用它们,否则可能会导致崩溃。
例如,您可以在logcat中看到以下消息:
1 2 3 4 | 06-05 00:46:39.083: I/dalvikvm(6286): Could not find method org.apache.http.client.protocol.RequestDefaultHeaders.<init>, referenced from method org.apache.http.impl.client.HttpClientBuilder.build 06-05 00:46:39.083: W/dalvikvm(6286): VFY: unable to resolve direct method 22794: Lorg/apache/http/client/protocol/RequestDefaultHeaders;.<init> (Ljava/util/Collection;)V 06-05 00:46:40.434: D/dalvikvm(6286): DexOpt: couldn't find static field Lorg/apache/http/impl/client/DefaultHttpRequestRetryHandler;.INSTANCE 06-05 00:46:40.434: W/dalvikvm(6286): VFY: unable to resolve static field 8420 (INSTANCE) in Lorg/apache/http/impl/client/DefaultHttpRequestRetryHandler; |
该特定消息是因为
回到最初的问题,使用较新的httpclient的唯一方法是重命名所有类,这样就不会发生名称冲突。这就是httpclientandroidlib所做的。
更进一步:DefaultHttpClient在4.3中确实已被弃用,但在Android中并没有弃用(除非您认为使用HttpUrlConnection的趋势是一种不受欢迎的弃用形式-在这种情况下,较新的HttpClient也不是首选的替代方法) )。为什么您要/需要更改它呢?
一年的答案,正确的答案是使用使用不同名称空间的apache库的官方android端口,从而避免冲突:https://hc.apache.org/httpcomponents-client-4.5.x/android-port.html