【问题标题】:Cancelling Http connection in android在android中取消Http连接
【发布时间】:2011-09-03 07:48:11
【问题描述】:

我正在使用org.apache.http,我有这个代码:

DefaultHttpClient client = new DefaultHttpClient();
HttpGet get = new HttpGet(url);

HttpResponse resp = client.execute(get);
HttpEntity entity = resp.getEntity();

InputStream input = entity.getContent();

...
//Read the bytes from input stream

这是我用来通过 Http 下载文件的代码,我想取消连接(可能是用户选择的) 关闭连接的优雅方式是什么。我找到了两种方法,都取消了下载。

  1. 关闭 inputsteram, input.close();这会导致 IOException。
  2. 中止 HttpGet 对象,get.abort() 会导致 SocketException。

我有try catch,所以没有错误,但没有抛出异常, 有没有办法取消或中止连接?

正确的做法是什么?

【问题讨论】:

  • 是的,在 doInBackground() 中我读取数据,在 onCancelled 中我需要一个正确的方法来取消下载,我目前正在从上面的代码中执行 get.abort()。
  • 我认为您无法取消获取。您只需取消异步任务,然后在 onCancelled() 中做任何您想做的事情,即忽略您可能得到的任何结果。也检查这个帖子:stackoverflow.com/questions/4880363/…
  • 正如我所说,我也在做同样的事情,在 onCancelled 方法中,我使用 get.abort() 中止下载并且它的发生没有任何问题,但是它抛出了我正在捕获的 socketException,我怀疑是没有捕获异常(或者说抛出异常)如何中止它。
  • 你可以试试EntityUtils.consume(entity)看看这个How to Answer[1] [1]: stackoverflow.com/a/7152466/885152
  • 消费才是正道。不会浪费任何资源,Java(除了本机代码)没有任何“真正的内存泄漏”。

标签: java android httpclient


【解决方案1】:

这样做的正确方法是将FIN 值发送到服务器端。

在 android 中,您无法选择参与此级别,因此您可以使用 C 自行实现,或使用您在问题中提到的方法之一。

【讨论】:

    【解决方案2】:

    在我看来,使用HttpUriRequest#about 是正确的方法。这将导致底层连接立即终止并将其从连接池中逐出。较新版本的 HttpClient(4.2 和更新)拦截由用户提前终止请求引起的 SocketException。问题是谷歌基于一个非常过时的版本(pre-beta1)发布了一个 HttpClient 的分支。如果您不能或不愿意使用较新版本的 HttpClient,您唯一的选择是在代码中捕获并丢弃 SocketException。

    【讨论】:

      【解决方案3】:

      使用这个

      client.getConnectionManager().closeExpiredConnections();
      client.getConnectionManager().shutdown();
      

      现在您可以决定将这两行代码写入何处。它将使用您创建的 DefaultHttpClient 对象关闭连接。

      如果这对您有帮助,请告诉我。

      【讨论】:

      • 对不起,我确实在寻找相同的功能,但使用 spring android rest 模板,它是完全不同的。
      • hmmm.... 只是一个问题,您是否使用 REST api 进行 Web 服务调用。因为我用过它们,上面两行帮助我按照要求关闭连接...... :)
      • REST api, spring android RestTemplate 是什么意思?因为我尝试使用这个 api 来访问 HttpClient,我可以执行这两行但没有任何效果,并且只要超时没有过期,连接就会打开并阻止其他人。
      • This 是我所说的 REST api Web 服务调用..
      • 我正在使用可能依赖于 apache 客户端 API 的 spring-android resttemplate,具体取决于您的代码运行的 android 版本。
      【解决方案4】:

      当你想中断连接时尝试取消任务: task.cancel(true); 这将取消任务和其中运行的线程。 检查此以供参考: public final boolean cancel (boolean mayInterruptIfRunning)

      自:API 级别 3 尝试取消此任务的执行。如果任务已完成、已被取消或由于其他原因无法取消,则此尝试将失败。如果成功,并且在调用取消时此任务尚未启动,则此任务不应该运行。如果任务已经启动,则 mayInterruptIfRunning 参数决定是否应该中断执行该任务的线程以尝试停止该任务。

      调用此方法将导致在 doInBackground(Object[]) 返回后在 UI 线程上调用 onCancelled(Object)。调用此方法可确保永远不会调用 onPostExecute(Object)。调用此方法后,应定期从 doInBackground(Object[]) 中检查 isCancelled() 返回的值,以尽早完成任务。

      参数 mayInterruptIfRunning 如果执行此任务的线程应该被中断,则为 true;否则,允许完成正在进行的任务。 退货 如果任务无法取消,则返回 false,通常是因为它已经正常完成;否则为真

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-10-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-09-29
        相关资源
        最近更新 更多