我正在使用HTTPUrlConnection连接到简单的RSS提要。它完美地运作。我想在连接中添加超时,因为我不希望我的应用程序在连接错误或其他情况下挂起。这是我使用的代码,setConnectTimeout方法没有任何效果。
HttpURLConnection http = (HttpURLConnection) mURL.openConnection();
http.setConnectTimeout(15000); //timeout after 15 seconds
...
如果它有助于我在Android上开发。
答案 0 :(得分:57)
您也应该尝试设置读取超时(http.setReadTimeout()
)。通常情况下,Web服务器会很乐意接受您的连接,但实际响应请求可能会很慢。
答案 1 :(得分: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.");
}
答案 2 :(得分: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,则取消而不是永远下载。
答案 3 :(得分:4)
我遇到了同样的问题。设置connectionTimeout
和readTimeout
似乎并没有像预期的那样返回异常,但确实如此。我花了很长时间检查URLConnection()
方法并了解发生了什么。在setConnectTimeout
的文档中有一个警告
“如果主机名解析为多个IP地址,则此客户端将尝试各自。如果连接到这些地址中的每一个都失败,则在连接尝试引发异常之前将经过多次超时。” 这意味着如果您的主机解决了10个ips,您的实际时间将为“10 * readTimeoutSet”。
您可以检查主机名here
的ips答案 4 :(得分:3)
http.setConnectTimeout(15000);
http.setReadTimeout(15000);
答案 5 :(得分:0)
原因是:
1.您已连接到wifi,但没有互联网连接。
2.您已连接到GSM数据,但传输非常差。
在两种情况下,您都会在大约20秒后收到主机异常。我认为正确的最佳方法是:
public boolean isOnline() {
final int TIMEOUT_MILLS = 3000;
final boolean[] online = {false};
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
if (netInfo != null && netInfo.isConnected()) {
final long time = System.currentTimeMillis();
new Thread(new Runnable() {
@Override
public void run() {
try {
URL url = new URL("http://www.google.com");
HttpURLConnection urlc = (HttpURLConnection) url.openConnection();
urlc.setConnectTimeout(TIMEOUT_MILLS);
urlc.setReadTimeout(TIMEOUT_MILLS);
urlc.connect();
if (urlc.getResponseCode() == 200) {
online[0] = true;
}
} catch (IOException e) {
loger.add(Loger.ERROR, e.toString());
}
}
}).start();
while (((System.currentTimeMillis() - time) <= TIMEOUT_MILLS)) {
if ((System.currentTimeMillis() - time) >= TIMEOUT_MILLS) {
return online[0];
}
}
}
return online[0];
}
记住-在异步任务或服务中使用它。
它是简单的解决方案,您正在使用HttpUrlConnection启动新线程(请记住使用start()而不是run())。比while循环,您要等待3秒钟才能得到结果。如果没有任何反应,则返回false。这样一来,您可以避免等待主机异常,并避免在没有Internet连接时无法运行setConnectTimeout()的问题。
答案 6 :(得分:0)
答案 7 :(得分:-2)
尝试在打开连接之前设置ConnectionTimeout
。