I\'m struggling with the following problem: My App makes sequence of requests to the http server using HttpClient. I use HttpPut for sending data to the server. First reques
Sounds like you don't consume the entity after you finish handling the response. Ensure you put the following code in the finally
block:
if (httpEntity != null) {
try {
httpEntity.consumeContent();
} catch (IOException e) {
Log.e(TAG, "", e);
}
}
I suggest you read the HttpClient Tutorial.
I've got the same trouble, when executing several requests in a loop.
You can solve it by reading all of response.getEntity()
.
I have had this same problem. I am consuming all the content.
What I found is if I do a garbage collection after issuing a request, everything works without having to close and create a new AndroidHttpClient:
System.gc();
It is enough for problem solution (I had the same):
EntityUtils.consume(response.getEntity());
Null check performed inside consume
I thought I would elaborate on the other answers. I experienced this problem also. The problem was because I was not consuming content.
It seems if you don't then the connection will hold on to it and you are not able to send a new request with this same connection. For me it was a particularly difficult bug to spot as I was using the BasicResponseHandler provided in android. The code looks like this...
public String handleResponse(final HttpResponse response)
throws HttpResponseException, IOException {
StatusLine statusLine = response.getStatusLine();
if (statusLine.getStatusCode() >= 300) {
throw new HttpResponseException(statusLine.getStatusCode(),
statusLine.getReasonPhrase());
}
HttpEntity entity = response.getEntity();
return entity == null ? null : EntityUtils.toString(entity);
}
So if there is an status line above 300 then I don't consume the content. And there was content in my case. I made my own class like this...
public class StringHandler implements ResponseHandler<String>{
@Override
public BufferedInputStream handleResponse(HttpResponse response) throws IOException {
public String handleResponse(final HttpResponse response)
throws HttpResponseException, IOException {
StatusLine statusLine = response.getStatusLine();
HttpEntity entity = response.getEntity();
if (statusLine.getStatusCode() >= 300) {
if (entity != null) {
entity.consumeContent();
}
throw new HttpResponseException(statusLine.getStatusCode(),
statusLine.getReasonPhrase());
}
return entity == null ? null : EntityUtils.toString(entity);
}
}
}
So basically in any case consume the content!
Sounds strange, but I had the exact same problem. The app I was working on was making several successive requests to download a bunch of thumbnail images to display in a ListView, and after the second one it would hang as if there was a dead lock in the HttpClient code.
The strange fix that I found was to use AndroidHttpClient instead of DefaultHttpClient. As soon as I did this, and I tried a lot of stuff before going this route, it started working just fine. Just remember to call client.close() when you're done with the request.
AndroidHttpClient is described in the documentation as DefaultHttpClient with "reasonable default settings and registered schemes for Android". Since this was introduced in api level 8 (Android 2.2), I dug up the source to duplicate these "default settings" so that I could use it further back than that api level. Here is my code for duplicating the defaults and a helper class with a static method for safely closing it
public class HttpClientProvider {
// Default connection and socket timeout of 60 seconds. Tweak to taste.
private static final int SOCKET_OPERATION_TIMEOUT = 60 * 1000;
public static DefaultHttpClient newInstance(String userAgent)
{
HttpParams params = new BasicHttpParams();
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
HttpProtocolParams.setContentCharset(params, HTTP.DEFAULT_CONTENT_CHARSET);
HttpProtocolParams.setUseExpectContinue(params, true);
HttpConnectionParams.setStaleCheckingEnabled(params, false);
HttpConnectionParams.setConnectionTimeout(params, SOCKET_OPERATION_TIMEOUT);
HttpConnectionParams.setSoTimeout(params, SOCKET_OPERATION_TIMEOUT);
HttpConnectionParams.setSocketBufferSize(params, 8192);
SchemeRegistry schReg = new SchemeRegistry();
schReg.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
schReg.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 443));
ClientConnectionManager conMgr = new ThreadSafeClientConnManager(params, schReg);
DefaultHttpClient client = new DefaultHttpClient(conMgr, params);
return client;
}
}
And in another class...
public static void safeClose(HttpClient client)
{
if(client != null && client.getConnectionManager() != null)
{
client.getConnectionManager().shutdown();
}
}