如何在 Java 中为 Android 设置 HttpResponse 超时
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/693997/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to set HttpResponse timeout for Android in Java
提问by Niko Gamulin
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!
谢谢!
采纳答案by kuester2000
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
.
在我的示例中,设置了两个超时。连接超时抛出java.net.SocketTimeoutException: Socket is not connected
和套接字超时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(例如 DefaultHttpClient 或 AndroidHttpClient)的参数,您可以使用函数setParams()。
httpClient.setParams(httpParameters);
回答by Pablo Santa Cruz
If your are using Jakarta's http client librarythen you can do something like:
如果您使用 Jakarta 的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);
回答by kuester2000
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 ....
我已经在 JellyBean 上成功使用了它,但也应该适用于旧平台......
HTH
HTH
回答by Sandeep
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);
回答by Bruno Peres
回答by foxundermon
you can creat HttpClient instance by the way with Httpclient-android-4.3.5,it can work well.
你可以顺便用Httpclient-android-4.3.5创建HttpClient实例,它可以很好地工作。
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();
回答by Learn OpenGL ES
If you're using the default http client, here's how to do it using the default http params:
如果您使用的是默认 http 客户端,以下是使用默认 http 参数的方法:
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/
原始信用转到http://www.jayway.com/2009/03/17/configuring-timeout-with-apache-httpclient-40/
回答by David Darias
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.
对于那些说@kuester2000的回答不起作用的人,请注意HTTP请求,首先尝试通过DNS请求找到主机IP,然后向服务器发出实际的HTTP请求,因此您可能还需要设置一个DNS 请求超时。
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.
如果您的代码在没有 DNS 请求超时的情况下工作,那是因为您能够访问 DNS 服务器或者您正在访问 Android DNS 缓存。顺便说一下,您可以通过重新启动设备来清除此缓存。
This code extends the original answer to include a manual DNS lookup with a custom timeout:
此代码扩展了原始答案以包含具有自定义超时的手动 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
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;
}
}
回答by androidevil
An option is to use the OkHttpclient, from Square.
一种选择是使用来自 Square的OkHttp客户端。
Add the library dependency
添加库依赖
In the build.gradle, include this line:
在 build.gradle 中,包含以下行:
compile 'com.squareup.okhttp:okhttp:x.x.x'
Where x.x.x
is the desired library version.
x.x.x
所需的库版本在哪里。
Set the client
设置客户端
For example, if you want to set a timeout of 60 seconds, do this way:
例如,如果要设置 60 秒的超时,请执行以下操作:
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:
ps:如果你的 minSdkVersion 大于 8,你可以使用TimeUnit.MINUTES
. 因此,您可以简单地使用:
okHttpClient.setReadTimeout(1, TimeUnit.MINUTES);
okHttpClient.setConnectTimeout(1, TimeUnit.MINUTES);
For more details about the units, see TimeUnit.
有关单位的更多详细信息,请参阅TimeUnit。
回答by Eco4ndly
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;
}