2011-07-26 22 views
35

我使用HTTPUrlConnection連接到一個簡單的RSS提要。它完美的作品。我想爲連接添加一個超時,因爲我不希望我的應用程序在連接不良或其他情況下掛起。這是我使用的代碼,setConnectTimeout方法沒有任何影響。HttpURLConnection setConnectTimeout()沒有效果

 HttpURLConnection http = (HttpURLConnection) mURL.openConnection(); 
     http.setConnectTimeout(15000); //timeout after 15 seconds 
... 

如果它可以幫助我在android上開發。

+1

有兩件事情你考慮的IPS。如果您不想讓應用掛起,請將連接方法放在單獨的線程中。其次,你說它「完美」工作,你在做什麼來模擬不良連接? – Otra

+0

@Otra我在使用progressdialog的單獨線程中擁有它。基本上發生的事情是,如果連接良好,那麼任務完成它的事情。但是如果連接不好,progressdialog會保持很長時間。爲了模擬一個不好的連接,我減少了超時時間。而不是給它15秒,1秒。只是爲了測試。或者那是錯的? –

+3

HttpURLConnection.setReadTimeout(mili sec); –

回答

16

你可能要麼/兩:
1)不要從連接
2)讀什麼不要捕捉&處理異常正確

如前所述here,類似於使用邏輯這個:

int TIMEOUT_VALUE = 1000; 
try { 
    URL testUrl = new URL("http://google.com"); 
    StringBuilder answer = new StringBuilder(100000); 

    long start = System.nanoTime(); 

    URLConnection testConnection = testUrl.openConnection(); 
    testConnection.setConnectTimeout(TIMEOUT_VALUE); 
    testConnection.setReadTimeout(TIMEOUT_VALUE); 
    BufferedReader in = new BufferedReader(new InputStreamReader(testConnection.getInputStream())); 
    String inputLine; 

    while ((inputLine = in.readLine()) != null) { 
     answer.append(inputLine); 
     answer.append("\n"); 
    } 
    in.close(); 

    long elapsed = System.nanoTime() - start; 
    System.out.println("Elapsed (ms): " + elapsed/1000000); 
    System.out.println("Answer:"); 
    System.out.println(answer); 
} catch (SocketTimeoutException e) { 
    System.out.println("More than " + TIMEOUT_VALUE + " elapsed."); 
} 
52

您應該嘗試設置讀取超時(http.setReadTimeout())。通常情況下,Web服務器會高興地接受您的連接,但實際響應請求可能會很慢。

+0

這對我有效。 – stevehs17

+1

如果連接到路由器但是互聯網連接斷開,沒有工作。 –

-1

嘗試在打開連接前設置ConnectionTimeout

+2

如何 - 構造函數是一種受保護的方法? – SK9

6

我有一個類似的問題 - 因爲HttpUrlConnection won't time out中下載。例如,如果您在下載時關閉wifi,我的繼續說它正在下載,卡住的比例相同。

我找到了一個解決方案,使用TimerTask連接到名爲DownloaderTask的AsyncTask。嘗試:

class Timeout extends TimerTask { 
    private DownloaderTask _task; 

    public Timeout(DownloaderTask task) { 
     _task = task; 
    } 

    @Override 
    public void run() { 
     Log.w(TAG,"Timed out while downloading."); 
     _task.cancel(false); 
    } 
}; 

然後在實際下載循環設置超時錯誤定時器:

    _outFile.createNewFile(); 
        FileOutputStream file = new FileOutputStream(_outFile); 
        out = new BufferedOutputStream(file); 
        byte[] data = new byte[1024]; 
        int count; 
        _timer = new Timer(); 
        // Read in chunks, much more efficient than byte by byte, lower cpu usage. 
        while((count = in.read(data, 0, 1024)) != -1 && !isCancelled()) { 
         out.write(data,0,count); 
         downloaded+=count; 
         publishProgress((int) ((downloaded/ (float)contentLength)*100)); 
         _timer.cancel(); 
         _timer = new Timer(); 
         _timer.schedule(new Timeout(this), 1000*20); 
        } 
        _timer.cancel(); 
        out.flush(); 

如果超時,並且不會在20秒內連1K下載,它取消,而不是似乎永遠下載。

+0

好主意,防止正在進行的連接和下載:) –

2

我正面臨同樣的問題。設置connectionTimeoutreadTimeout似乎並沒有像預期的那樣返回異常,但真的如此。我花了我時間檢查URLConnection()方法並瞭解正在發生的事情。在setConnectTimeout的文檔中有一個警告

「如果主機名解析爲多個IP地址,則該客戶端將嘗試每個IP地址。如果連接到這些地址的每個失敗,則會在連接嘗試引發異常之前經過多個超時。 「 這意味着如果您的主機已解決10個ips,您的實際超時時間將爲「10 * readTimeoutSet」。

您可以檢查主機名here

1
http.setConnectTimeout(15000); 
http.setReadTimeout(15000);