我有一个线程正在连接到一个url以获取一些数据。
有时方法httpConnection.connect();
花费了太多的时间来获得响应,我想将这个连接线程的加载对话框限制为5段。
我尝试在代码中添加超时,但不起作用!!
URL formattedUrl = new URL(url);
URLConnection connection = formattedUrl.openConnection();
connection.setConnectTimeout(5000);
connection.setReadTimeout(5000);
HttpURLConnection httpConnection = (HttpURLConnection) connection;
httpConnection.setAllowUserInteraction(false);
httpConnection.setInstanceFollowRedirects(true);
httpConnection.setRequestMethod("GET");
httpConnection.setConnectTimeout(5000);
httpConnection.setReadTimeout(5000);
httpConnection.connect();
因此,当5000秒过去时,或者当用户按下手机上的后退键时,我必须停止连接方法和线程。
如何做到这一点?我找不到关于在android中使用url连接线程完成这项工作的信息。
感谢
URLConnection上的超时设置不足以提供所需的超时控制。原因是:
-
setConnectTimeout()设置仅与服务器建立连接的超时。因此,只有在打开连接时,无法在规定的时间内建立连接,才会触发超时。
-
setReadTimeount()设置读取可用数据的超时时间。为此,只有当单个读取操作块的时间超过设置的时间量时,才会触发超时。因此,即使在慢速连接上,每次读取操作也很可能永远不会接近超时阈值,但读取所有数据的总时间相当长。
将超时应用于整个读取工作单元的一个解决方案是使用Java 5及更高版本中的并发功能。特别是,ExecutorService和Future的使用应该足够。
Runnable task = new Runnable() {
public void run() {
// original code to read data from a URL
}
};
ExecutorService executor = Executors.newSingleThreadExecutor(); // or any other implementation
Future<?> future = executor.submit(task);
try {
future.get(5, TimeUnit.SECONDS); // wait 5 seconds for task to complete
// success
} catch (TimeoutException ex) {
// handle timeout
} finally {
executor.shutdownNow(); // cleanup
}
Brent Worden的答案是正确的。但他的解决方案存在问题。如果任务超时开始,调用future.get
的线程将按预期获得异常。但是,执行Runnable.run()
方法的工作线程可能仍在等待连接或读取完成。
解决这个问题很困难。据我所知,解除对正在等待套接字连接或套接字流读写的线程的调用的唯一可靠方法是在Socket
对象上调用close()
。使用这种方法(这里)的问题是标准的HttpUrlConnection
对象没有公开Socket
对象。
我的建议是使用ApacheHttp客户端库。这个问题解释了如果您使用HttpClient,如何中止请求:取消HttpClient请求
您只需要调用URLConnection.setConnectTimeout(millis)就可以实现您的要求。如果指定的超时过期,将引发SocketTimeoutException。
try {
HttpURLConnection con = (HttpURLConnection) new URL(url).openConnection();
con.setConnectTimeout(5000); //set timeout to 5 seconds
} catch (java.net.SocketTimeoutException e) {
//DO SOMETHING
} catch (java.io.IOException e) {
//DO SOMETHING
}
值得注意的是,上面写着:
此方法的某些非标准实现可能会忽略指定的超时。要查看连接超时设置,请拨打getConnectTimeout()。
不能,如果停止线程,线程所属的进程将结束。