2010-06-19 71 views
41

我正在编写一个连接到web服务的应用程序,如果它无法连接,我不希望它等待太久。因此,我设置了httpparams的connectionTimeout。但它似乎没有任何影响。Android上的http连接超时不工作

测试我暂时关闭WLAN。应用程序尝试连接相当一段时间(比我想要的时间多3秒),然后抛出UnknownHostException。

这里是我的代码:

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

任何人有任何想法我错过了什么?

回答

74

尝试做这样说:

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; 

然后,您可以搭乘可能ConnectTimeoutException

+3

如何通知系统有关超时和需要处理的异常? – vokilam 2011-02-28 08:45:01

+1

@VokilaM:我刚刚编辑了我的答案。 – Cristian 2011-02-28 13:12:05

+3

我在30+秒后仍然收到UnknownHostException。在这种情况下,该设备连接到无线路由器,但没有互联网接入。任何线索如何使这个电话处理?否则,我可能会回落到一个外部计时器... :( – hooby3dfx 2013-02-22 21:17:37

1

此方法适用于我:

AndroidHttpTransport androidHttpTransport = new AndroidHttpTransport(endpoint, 3000) ; 
0
HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection); 
// Set the default socket timeout (SO_TIMEOUT) 
+0

这不是问题的答案,因为该方法调用已经是下面代码的一部分; *另一个提示*:使用代码格式更好的演示文稿... – Trinimon 2013-03-22 08:36:19

9

有了显着的解决方案超过30秒后,我仍然得到一个UnknownHostException异常。在这种情况下,该设备连接到无线路由器,但没有互联网接入。

采取的方法是启动一个只尝试解析主机名的AsyncTask。阻塞呼叫每250毫秒检查一次,看看它是否成功,4秒后它将取消任务并返回。

这是我做过什么来解决这个问题:

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

} 

然后,我想做一个网络调用的任何时间,这就是所谓的函数的开头:

if(!resolveDns()){ 
     return null; 
    } 
+0

这就是我一直在寻找。谢了哥们! – 2015-12-29 04:47:41

2

见:https://stackoverflow.com/a/20031077/2609238

问题可能出现在Apache HTTP Client中。请参阅HTTPCLIENT-1098。在4.1.2中修复。

超时异常会尝试将DNS反向IP,以用于日志记录目的。这需要额外的时间,直到实际发生异常。