我正在将 HttpClient 4.2.1 与 PoolingClientConnectionManager 一起使用,并且我发现我的应用程序将在尝试获取 http 连接后开始挂起。如果您未能使用 HttpEntity,则此症状似乎是一个常见错误,因为 4.2.1 依赖于关闭 Content 的流以将其返回到池的连接。
这是我组装 HttpClients 及其池的方式
HttpClient standardClient = null;
HttpClient cachedClient = null;
PoolingClientConnectionManager connectionManager = null;
protected synchronized HttpClient getStandardClient() {
if ( standardClient == null ) {
connectionManager = new PoolingClientConnectionManager();
connectionManager.setMaxTotal(2);
connectionManager.closeIdleConnections(120, TimeUnit.SECONDS);
standardClient = new DecompressingHttpClient( new DefaultHttpClient (connectionManager));
Log.i(tag, "Creating ConnectionManager and standard http client");
}
return standardClient;
}
protected synchronized HttpClient getCachedClient() {
if ( cachedClient == null ) {
CacheConfig cacheConfig = new CacheConfig();
cacheConfig.setMaxObjectSize( 512*1024 );
cacheConfig.setMaxCacheEntries( 10 );
cachedClient = new CachingHttpClient(getStandardClient(),
getCacheStorage(),
cacheConfig);
Log.i(tag, "Creating CachingHttpClient");
}
return cachedClient;
}
如您所见,我有两个客户。包装标准客户端的缓存 http 客户端。
现在我发现,如果我删除 cachedClient 并且只使用 standardClient,我不会遇到池挂起和孤立连接的任何问题。
查看 CachingHttpClient 的源代码,它似乎没有使用底层实体。有没有其他人经历过这个?
任何人都可以看到我的代码中的任何错误以及我是如何配置和使用 HttpClient 的吗?有谁知道我可以在我的代码中做些什么来正确地让后端实体被正确使用?
顺便说一句,这是我使用 http 客户端并使用它们的方式......
HttpClient httpClient = cacheOkay ? getCachedClient() : getStandardClient();
HttpResponse response = httpClient.execute(request, localContext);
HttpEntity resEntity = response.getEntity();
int responseStatus = response.getStatusLine().getStatusCode();
byte[] responseBody = EntityUtils.toByteArray(resEntity);
EntityUtils.consume(resEntity);
此外,对于那些想知道这是在 Android 上的人,我使用 JarJar 将 HttpClient 4.2.1 重新打包为备用包结构,因此它不会与 Android 附带的旧 HttpClient 类冲突。但尽管重新打包代码是 100% 4.2.1。我只是提到这一点是为了避免在 Android 上运行 HttpClient 4.2.1 时出现任何冲突建议。