Android Httpclient Hangs on Second Request to the Server (Connection Timed Out)

android httpclient hangs on second request to the server (connection timed out)

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();
}
}

Android HttpClient hangs simultaneous requests until I execute request to another host

This is most likely due to how you are constructing the ThreadSafeClientConnManager you are using. If you change the order slightly you should get a better result.

    HttpParams params = new BasicHttpParams();
// The params are read in the ctor of the pool constructed by
// ThreadSafeClientConnManager, and need to be set before constructing it.
ConnManagerParams.setMaxTotalConnections(params, 200);
ConnPerRoute cpr = new ConnPerRoute() {
@Override
public int getMaxForRoute(HttpRoute httpRoute) {
return 50;
}
};
ConnManagerParams.setMaxConnectionsPerRoute(params, cpr);
SchemeRegistry schemeRegistry = new SchemeRegistry();
schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
ClientConnectionManager cm = new ThreadSafeClientConnManager(params, schemeRegistry);

HttpClient executes requests multiple time if request timed out

I found that it is HttpClient's default behaviour to execute requests 4 times if it fails. I am not sure about other kind of failures but at least with time out.

To disable this behaviour do this :

DefaultHttpClient client = new DefaultHttpClient();
// Disable default behavior of HttpClient of retrying requests in case of failure
((AbstractHttpClient) client).setHttpRequestRetryHandler(new DefaultHttpRequestRetryHandler(0, false));

Here retry count is set to 0 to disable retry.

I found solution from this blog.

HttpClient stuck without any exception

This code is now deprecated (get HttpParams, etc). A better way is:

RequestConfig defaultRequestConfig = RequestConfig.custom()
.setCookieSpec(CookieSpecs.BEST_MATCH)
.setExpectContinueEnabled(true)
.setStaleConnectionCheckEnabled(true)
.setTargetPreferredAuthSchemes(Arrays.asList(AuthSchemes.NTLM, AuthSchemes.DIGEST))
.setProxyPreferredAuthSchemes(Arrays.asList(AuthSchemes.BASIC))
.build();

HttpGet httpGet = new HttpGet(url);
RequestConfig requestConfig = RequestConfig.copy(defaultRequestConfig)
.setSocketTimeout(5000)
.setConnectTimeout(5000)
.setConnectionRequestTimeout(5000)
.build();
httpGet.setConfig(requestConfig);


Related Topics



Leave a reply



Submit