PoolingClientConnectionManager で HttpClient 4.2.1 を使用していますが、使用後に http 接続を取得しようとするとアプリがハングし始めることがわかりました。4.2.1 はコンテンツのストリームを閉じてプールへの接続を返すことに依存しているため、この症状は HttpEntity の消費に失敗した場合によくある間違いのようです。
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;
}
ご覧のとおり、クライアントが 2 つあります。標準クライアントをラップするキャッシュ 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 を実行する際の競合の可能性を避けるために、これについて言及しただけです。