Android 上的 Http 连接超时不起作用
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3075506/
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
Http connection timeout on Android not working
提问by ascu
I'm writing an application that connects to a webservice and I don't want it to wait too long if it can't get a connection. I therefore set the connectionTimeout of the httpparams. But it doesn't seem to have any effect whatsoever.
我正在编写一个连接到网络服务的应用程序,如果无法连接,我不希望它等待太久。因此,我设置了 httpparams 的 connectionTimeout。但它似乎没有任何影响。
To test I turn of my WLAN temporarily. The application tries to connect for quite some time (way more than the 3 seconds I want) and then throws an UnknownHostException.
为了测试我暂时关闭了我的 WLAN。应用程序尝试连接很长一段时间(超过我想要的 3 秒),然后抛出 UnknownHostException。
Here is my code:
这是我的代码:
try{
HttpClient httpclient = new DefaultHttpClient();
HttpParams params = httpclient.getParams();
HttpConnectionParams.setConnectionTimeout(params, 3000);
HttpConnectionParams.setSoTimeout(params, 3000);
httppost = new HttpPost(URL);
StringEntity se = new StringEntity(envelope,HTTP.UTF_8);
httppost.setEntity(se);
//Code stops here until UnknownHostException is thrown.
BasicHttpResponse httpResponse = (BasicHttpResponse) httpclient.execute(httppost);
HttpEntity entity = httpResponse.getEntity();
return entity;
}catch (Exception e){
e.printStackTrace();
}
Anyone have any ideas what I missed?
任何人都知道我错过了什么?
回答by Cristian
Try to do it this way:
尝试这样做:
HttpPost httpPost = new HttpPost(url);
StringEntity se = new StringEntity(envelope,HTTP.UTF_8);
httpPost.setEntity(se);
HttpParams httpParameters = new BasicHttpParams();
// Set the timeout in milliseconds until a connection is established.
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 = 3000;
HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);
DefaultHttpClient httpClient = new DefaultHttpClient(httpParameters);
BasicHttpResponse httpResponse = (BasicHttpResponse) httpClient.execute(httpPost);
HttpEntity entity = httpResponse.getEntity();
return entity;
You then can catch a possible ConnectTimeoutException
.
然后,您可以捕获一个可能的ConnectTimeoutException
.
回答by hooby3dfx
With the marked solution I am still getting a UnknownHostException after 30+ seconds. In this case the device is connected to a wifi router but there is no internet access.
使用标记的解决方案,我在 30+ 秒后仍然收到 UnknownHostException。在这种情况下,设备已连接到 wifi 路由器,但无法访问互联网。
The approach taken was to kick off an AsyncTask that will just attempt to resolve the hostname. The blocking call checks every 250 ms to see if it succeeded, and after 4 seconds it will cancel the task and return.
所采取的方法是启动一个 AsyncTask,它只会尝试解析主机名。阻塞调用每 250 毫秒检查一次是否成功,并在 4 秒后取消任务并返回。
This is what I did to solve it:
这是我为解决它所做的:
private boolean dnsOkay = false;
private static final int DNS_SLEEP_WAIT = 250;
private synchronized boolean resolveDns(){
RemoteDnsCheck check = new RemoteDnsCheck();
check.execute();
try {
int timeSlept = 0;
while(!dnsOkay && timeSlept<4000){
//Log.d("RemoteDnsCheck", "sleeping");
Thread.sleep(DNS_SLEEP_WAIT);
timeSlept+=DNS_SLEEP_WAIT;
//Log.d("RemoteDnsCheck", "slept");
}
} catch (InterruptedException e) {
}
if(!dnsOkay){
Log.d("resolveDns", "cancelling");
check.cancel(true);
Log.d("resolveDns", "cancelled");
}
return dnsOkay;
}
private class RemoteDnsCheck extends AsyncTask<Void, Void, Void>{
@Override
protected Void doInBackground(Void... params) {
try {
Log.d("RemoteDnsCheck", "starting");
dnsOkay = false;
InetAddress addr = InetAddress.getByName(baseServiceURL);
if(addr!=null){
Log.d("RemoteDnsCheck", "got addr");
dnsOkay = true;
}
} catch (UnknownHostException e) {
Log.d("RemoteDnsCheck", "UnknownHostException");
}
return null;
}
}
Then, any time I want to do a web call, this is called at the beginning of the function:
然后,每当我想进行网络调用时,都会在函数的开头调用它:
if(!resolveDns()){
return null;
}
回答by noam
See: https://stackoverflow.com/a/20031077/2609238
参见:https: //stackoverflow.com/a/20031077/2609238
The problem might be in the Apache HTTP Client. See HTTPCLIENT-1098. Fixed in 4.1.2.
问题可能出在 Apache HTTP 客户端中。请参阅 HTTPCLIENT-1098。已在 4.1.2 中修复。
The timeout exception tries to reverse DNS the IP, for logging purposes. This takes an additional time until the exception is actually fired.
超时异常尝试反转 DNS 的 IP,以用于日志记录。这需要额外的时间才能真正触发异常。
回答by Jr.
This method works for me :
这种方法对我有用:
AndroidHttpTransport androidHttpTransport = new AndroidHttpTransport( endpoint, 3000) ;
回答by user2198255
HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection);
// Set the default socket timeout (SO_TIMEOUT)