如何在Java中为Android设置HttpResponse超时

我已经创build了以下函数来检查连接状态:

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

当我closures服务器进行testing时,执行等待很长时间

 HttpResponse response = httpClient.execute(method); 

有谁知道如何设置超时,以避免等待太久?

谢谢!

在我的例子中,设置了两个超时。 连接超时会抛出“java.net.SocketTimeoutException:套接字未连接”,套接字超时“java.net.SocketTimeoutException:操作超时”。

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

如果你想设置任何现有的HTTPClient的参数(例如DefaultHttpClient或AndroidHttpClient),你可以使用函数setParams()

 httpClient.setParams(httpParameters); 

在客户端上设置设置:

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

我已经成功地使用了这个软糖,但也应该适用于较老的平台。

HTH

如果你正在使用雅加达的http客户端库,那么你可以做一些事情:

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

如果您使用的是默认的http客户端,那么使用默认的http params来做到这一点:

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

原来的功劳去http://www.jayway.com/2009/03/17/configuring-timeout-with-apache-httpclient-40/

对于那些认为@ kuester2000的回答不起作用的请注意HTTP请求,首先尝试用DNS请求查找主机IP,然后将实际的HTTP请求发送给服务器,因此您可能还需要设置一个超时的DNS请求。

如果你的代码没有DNS请求的超时工作,这是因为你能够到达一个DNS服务器,或者你正在打的Android DNScaching。 顺便说一下,您可以通过重新启动设备来清除此caching。

此代码将原始答案扩展为包含手动DNS查找与自定义超时:

 //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 

使用方法:

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

这个class是从这个博客文章 。 去检查你的评论,如果你会使用它。

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

如果您正在使用HttpURLConnection ,请调用setConnectTimeout()

 URL url = new URL(myurl); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setConnectTimeout(CONNECT_TIMEOUT); 

http://developer.android.com/reference/java/net/URLConnection.html#setConnectTimeout(int);

你可以通过HttpClient-android-4.3.5的方式创buildHttpClient实例,它可以很好地工作。

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

一个选项是使用Square的OkHttp客户端。

添加库依赖项

在build.gradle中,包含这一行:

 compile 'com.squareup.okhttp:okhttp:xxx' 

其中xxx是所需的库版本。

设置客户端

例如,如果要设置60秒的超时时间,请执行以下操作:

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

ps:如果你的minSdkVersion大于8,你可以使用TimeUnit.MINUTES 。 所以,你可以简单地使用:

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

有关单位的更多细节,请参阅TimeUnit 。