How to set HttpResponse timeout for Android in Java
Asked Answered
F

10

337

I have created the following function for checking the connection status:

private void checkConnectionStatus() {
    HttpClient httpClient = new DefaultHttpClient();

    try {
      String url = "http://xxx.xxx.xxx.xxx:8000/GaitLink/"
                   + strSessionString + "/ConnectionStatus";
      Log.d("phobos", "performing get " + url);
      HttpGet method = new HttpGet(new URI(url));
      HttpResponse response = httpClient.execute(method);

      if (response != null) {
        String result = getResponse(response.getEntity());
        ...

When I shut down the server for testing the execution waits a long time at line

HttpResponse response = httpClient.execute(method);

Does anyone know how to set the timeout in order to avoid waiting too long?

Thanks!

Frankish answered 29/3, 2009 at 2:15 Comment(1)
This API doesn't provide a way to set a timeout for the DNS lookup, which will be used behind the scenes.Typhus
R
625

In my example, two timeouts are set. The connection timeout throws java.net.SocketTimeoutException: Socket is not connected and the socket timeout java.net.SocketTimeoutException: The operation timed out.

HttpGet httpGet = new HttpGet(url);
HttpParams httpParameters = new BasicHttpParams();
// Set the timeout in milliseconds until a connection is established.
// The default value is zero, that means the timeout is not used. 
int timeoutConnection = 3000;
HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection);
// Set the default socket timeout (SO_TIMEOUT) 
// in milliseconds which is the timeout for waiting for data.
int timeoutSocket = 5000;
HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);

DefaultHttpClient httpClient = new DefaultHttpClient(httpParameters);
HttpResponse response = httpClient.execute(httpGet);

If you want to set the Parameters of any existing HTTPClient (e.g. DefaultHttpClient or AndroidHttpClient) you can use the function setParams().

httpClient.setParams(httpParameters);
Rus answered 14/10, 2009 at 9:39 Comment(14)
What if you are using AndroidHttpClient? How would you attach the parameters?Introduction
What will the HttpResponse return if the connection times out? At the moment once my HTTP request is made, I then check the status code upon the call returning, however I get a NullPointerException when checking this code if the call has timed out... basically, how do I handle the situation when the call does timeout? (I'm using very similar code to your answer given)Forbear
Hi, sorry but I do get "The method setParams(HttpParams) is undefined for the type AndroidHttpClient".Torosian
@Torosian - Despite the documentation, AndroidHttpClient does not extend DefaultHttpClient; rather, it implements HttpClient. You'll need to use DefaultHttpClient to have available the setParams(HttpParams) method.Armour
@Ted Hopp: thanks! I found out that setParams() works for HttpRequest, so this is a solution if one wants to use AndroidHttpClient.Torosian
When I insert httpParameters, it should show to me this exceptions? Or I just need to catch? because the only exceptions I can see are ClientProtocolException and IOExceptionPapal
Readers must know its default value see docsAirbrush
Hey guys,t hanks for the excellent answer. But, I would like to show a toast to the users on connection timeout ... any way I can detect when the connection times out?Principalities
Hi Guys, I am using HTTPClient and what will be my connection time out if i do not set explicitly. I mean what will be default connection time out..i think it is 15 secs. Am i right or do i need to set explicitly.Cement
@Aki httpClient.execute() requires you to catch IOException... You can put your Toast message there.Bath
Doesn't work. I tested on my Sony and Moto, they all get tucked.Chorion
This scenario does not handle "device is connected to wifi and wifi is not connected to Internet "....not working at all the default time out of HTTP Client is 40 sec and that of AndroidHTTPClient is 20 sec we can not low it down to our desired timeCharged
For those saying that this does not work, please be aware that HTTP requests, first try to find the host IP with a DNS request and then makes the actual HTTP request to the server, so you also need to set a timeout for the DNS request. I will post an answer with the full code to do this.Teriann
if internet connection is fast is it have to wait for 8 secLase
C
13

To set settings on the client:

AndroidHttpClient client = AndroidHttpClient.newInstance("Awesome User Agent V/1.0");
HttpConnectionParams.setConnectionTimeout(client.getParams(), 3000);
HttpConnectionParams.setSoTimeout(client.getParams(), 5000);

I've used this successfully on JellyBean, but should also work for older platforms ....

HTH

Cappella answered 29/8, 2012 at 15:56 Comment(1)
whats the relation with HttpClient?Wideopen
D
8

If your are using Jakarta's http client library then you can do something like:

        HttpClient client = new HttpClient();
        client.getParams().setParameter(HttpClientParams.CONNECTION_MANAGER_TIMEOUT, new Long(5000));
        client.getParams().setParameter(HttpClientParams.SO_TIMEOUT, new Integer(5000));
        GetMethod method = new GetMethod("http://www.yoururl.com");
        method.getParams().setParameter(HttpMethodParams.SO_TIMEOUT, new Integer(5000));
        method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
        int statuscode = client.executeMethod(method);
Dreary answered 29/3, 2009 at 2:23 Comment(3)
HttpClientParams.CONNECTION_MANAGER_TIMEOUT is unknownBoarding
You should use client.getParams().setIntParameter(..) for the *_TIMEOUT paramsGlandulous
How to find? Device is connected to wifi but not actually active data getting through wifi.Malan
R
7

If you're using the default http client, here's how to do it using the default http params:

HttpClient client = new DefaultHttpClient();
HttpParams params = client.getParams();
HttpConnectionParams.setConnectionTimeout(params, 3000);
HttpConnectionParams.setSoTimeout(params, 3000);

Original credit goes to http://www.jayway.com/2009/03/17/configuring-timeout-with-apache-httpclient-40/

Reinert answered 15/1, 2015 at 2:57 Comment(0)
T
5

For those saying that the answer of @kuester2000 does not work, please be aware that HTTP requests, first try to find the host IP with a DNS request and then makes the actual HTTP request to the server, so you may also need to set a timeout for the DNS request.

If your code worked without the timeout for the DNS request it's because you are able to reach a DNS server or you are hitting the Android DNS cache. By the way you can clear this cache by restarting the device.

This code extends the original answer to include a manual DNS lookup with a custom timeout:

//Our objective
String sURL = "http://www.google.com/";
int DNSTimeout = 1000;
int HTTPTimeout = 2000;

//Get the IP of the Host
URL url= null;
try {
     url = ResolveHostIP(sURL,DNSTimeout);
} catch (MalformedURLException e) {
    Log.d("INFO",e.getMessage());
}

if(url==null){
    //the DNS lookup timed out or failed.
}

//Build the request parameters
HttpParams params = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(params, HTTPTimeout);
HttpConnectionParams.setSoTimeout(params, HTTPTimeout);

DefaultHttpClient client = new DefaultHttpClient(params);

HttpResponse httpResponse;
String text;
try {
    //Execute the request (here it blocks the execution until finished or a timeout)
    httpResponse = client.execute(new HttpGet(url.toString()));
} catch (IOException e) {
    //If you hit this probably the connection timed out
    Log.d("INFO",e.getMessage());
}

//If you get here everything went OK so check response code, body or whatever

Used method:

//Run the DNS lookup manually to be able to time it out.
public static URL ResolveHostIP (String sURL, int timeout) throws MalformedURLException {
    URL url= new URL(sURL);
    //Resolve the host IP on a new thread
    DNSResolver dnsRes = new DNSResolver(url.getHost());
    Thread t = new Thread(dnsRes);
    t.start();
    //Join the thread for some time
    try {
        t.join(timeout);
    } catch (InterruptedException e) {
        Log.d("DEBUG", "DNS lookup interrupted");
        return null;
    }

    //get the IP of the host
    InetAddress inetAddr = dnsRes.get();
    if(inetAddr==null) {
        Log.d("DEBUG", "DNS timed out.");
        return null;
    }

    //rebuild the URL with the IP and return it
    Log.d("DEBUG", "DNS solved.");
    return new URL(url.getProtocol(),inetAddr.getHostAddress(),url.getPort(),url.getFile());
}   

This class is from this blog post. Go and check the remarks if you will use it.

public static class DNSResolver implements Runnable {
    private String domain;
    private InetAddress inetAddr;

    public DNSResolver(String domain) {
        this.domain = domain;
    }

    public void run() {
        try {
            InetAddress addr = InetAddress.getByName(domain);
            set(addr);
        } catch (UnknownHostException e) {
        }
    }

    public synchronized void set(InetAddress inetAddr) {
        this.inetAddr = inetAddr;
    }
    public synchronized InetAddress get() {
        return inetAddr;
    }
}
Teriann answered 26/7, 2015 at 23:54 Comment(0)
H
3

An option is to use the OkHttp client, from Square.

Add the library dependency

In the build.gradle, include this line:

compile 'com.squareup.okhttp:okhttp:x.x.x'

Where x.x.x is the desired library version.

Set the client

For example, if you want to set a timeout of 60 seconds, do this way:

final OkHttpClient okHttpClient = new OkHttpClient();
okHttpClient.setReadTimeout(60, TimeUnit.SECONDS);
okHttpClient.setConnectTimeout(60, TimeUnit.SECONDS);

ps: If your minSdkVersion is greater than 8, you can use TimeUnit.MINUTES. So, you can simply use:

okHttpClient.setReadTimeout(1, TimeUnit.MINUTES);
okHttpClient.setConnectTimeout(1, TimeUnit.MINUTES);

For more details about the units, see TimeUnit.

Hulton answered 7/8, 2015 at 4:15 Comment(1)
In the current version of OkHttp, timeouts need to be set differently: https://github.com/square/okhttp/blob/master/samples/guide/src/main/java/okhttp3/recipes/ConfigureTimeouts.javaSavil
K
1
HttpParams httpParameters = new BasicHttpParams();
            HttpProtocolParams.setVersion(httpParameters, HttpVersion.HTTP_1_1);
            HttpProtocolParams.setContentCharset(httpParameters,
                    HTTP.DEFAULT_CONTENT_CHARSET);
            HttpProtocolParams.setUseExpectContinue(httpParameters, true);

            // Set the timeout in milliseconds until a connection is
            // established.
            // The default value is zero, that means the timeout is not used.
            int timeoutConnection = 35 * 1000;
            HttpConnectionParams.setConnectionTimeout(httpParameters,
                    timeoutConnection);
            // Set the default socket timeout (SO_TIMEOUT)
            // in milliseconds which is the timeout for waiting for data.
            int timeoutSocket = 30 * 1000;
            HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);
Kato answered 3/7, 2014 at 12:38 Comment(1)
Not complete. Whats the relation with HttpClient?Wideopen
A
1

If you are using the HttpURLConnection, call setConnectTimeout() as described here:

URL url = new URL(myurl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(CONNECT_TIMEOUT);
Aegaeon answered 4/9, 2014 at 22:50 Comment(1)
The description is more like the timeout to establish the connection, instead of http request ?Alben
D
1

you can creat HttpClient instance by the way with Httpclient-android-4.3.5,it can work well.

 SSLContext sslContext = SSLContexts.createSystemDefault();
        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
                sslContext,
                SSLConnectionSocketFactory.STRICT_HOSTNAME_VERIFIER);
                RequestConfig.Builder requestConfigBuilder = RequestConfig.custom().setCircularRedirectsAllowed(false).setConnectionRequestTimeout(30*1000).setConnectTimeout(30 * 1000).setMaxRedirects(10).setSocketTimeout(60 * 1000);
        CloseableHttpClient hc = HttpClients.custom().setSSLSocketFactory(sslsf).setDefaultRequestConfig(requestConfigBuilder.build()).build();
Dinghy answered 24/11, 2014 at 7:37 Comment(0)
R
0
public boolean isInternetWorking(){
    try {
        int timeOut = 5000;
        Socket socket = new Socket();
        SocketAddress socketAddress = new InetSocketAddress("8.8.8.8",53);
        socket.connect(socketAddress,timeOut);
        socket.close();
        return true;
    } catch (IOException e) {
        //silent
    }
    return false;
}
Rivard answered 27/2, 2018 at 6:28 Comment(1)
Which server does it represent? "8.8.8.8",53Beam

© 2022 - 2024 — McMap. All rights reserved.