在Android中导入更新的Apache HttpClient jar

Jja*_*ang 6 java apache android apache-httpcomponents

我正在尝试从我的Android客户端发送HTTP/HTTPS发布请求.

为什么我的代码失败了?

至今

我创建了一个apache类/ HttpClient调用.一切都很好:

HttpClient httpClient = new DefaultHttpClient();
Run Code Online (Sandbox Code Playgroud)

我已经读过这个方法已被弃用,所以我已经切换到新推荐的方法:

HttpClient httpClient = HttpClientBuilder.create().build();
Run Code Online (Sandbox Code Playgroud)

Eclipse没有这个类,所以我不得不下载Apache HttpClient 4.3.3.我通过将其复制到libs文件夹并将其添加到我的构建路径(导入的httpclient,httpclient-cache,httpcore,httpmime,fluent-hc,commons-logging,commons-codec)将其导入到我的项目中.

错误信息

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
Run Code Online (Sandbox Code Playgroud)

最近的代码

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;
}
Run Code Online (Sandbox Code Playgroud)

mat*_*ash 5

问题是Android已经包含了一个旧版本(目前还不清楚 Apache HttpClient 究竟是哪个,但大概是4.0beta2).

当您将新版本的jar添加为应用程序的库时,加载APK时将忽略重复的类.由于HttpClient中的一些类依赖于对这些其他类进行的修改,因此dalvik尽其所能(例如删除引用,&c)但除非它们被有条件地使用,否则这可能会导致崩溃.

例如,您可以在logcat中看到这些消息:

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;
Run Code Online (Sandbox Code Playgroud)

这个特殊的消息是因为DefaultHttpRequestRetryHandler 在4.3中有一个新的INSTANCE静态字段,它在Android中没有.还有更多.

回到原来的问题,使用更新的httpclient的唯一方法是重命名所有类,这样就不会发生这些名称冲突.这就是httpclientandroidlib所做的.

更进一步说:DefaultHttpClient 确实在4.3中被弃用了,但在Android中并没有被弃用(除非你考虑使用HttpUrlConnection这种隐形形式的弃用的趋势 - 在这种情况下,新的HttpClient也不是首选的替代方案).为什么你想要/需要改变它?