2010-06-19 69 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,以用於日誌記錄目的。這需要額外的時間,直到實際發生異常。