Android KitKat HttpURLConnection 断开 AsyncTask

Posted

技术标签:

【中文标题】Android KitKat HttpURLConnection 断开 AsyncTask【英文标题】:Android KitKat HttpURLConnection disconnect AsyncTask 【发布时间】:2013-12-04 22:41:08 【问题描述】:

在我的应用程序中,我在AsyncTask 中使用HttpURLConnection 下载文件。如果文件下载时间过长,那么我想取消它;我通过关闭流并在HttpURLConnection 对象上调用disconnect() 来做到这一点。多年来,该代码在 android 中完美运行。然而,既然 KitKat 出来了,问题就出现了。具体来说,disconnect() 调用本身需要几秒钟或更长时间才能完成。在 KitKat 之前的设备中,它需要一毫秒或更短的时间。真正奇怪的是,当我在单独的线程上执行断开调用时,它又真的很快了。所以在AsyncTaskdoInBackground方法中调用它一定是个问题。需要注意的一件事是我的AsyncTask 确实有一个Looper.prepare() 电话。

有谁知道 KitKat 和其他 Android 版本的区别是什么?我梳理了更改列表,没有看到与此问题相关的任何内容。

【问题讨论】:

遇到同样的问题 我看到了类似的问题;我做了一些调查,这是关闭流的方式发生了变化。我已经详细介绍了here - 不幸的是我还没有修复。 同样的结果,在单独的线程上断开连接也会给我​​带来同样的延迟。 【参考方案1】:

Kitkat 似乎使用了 okhttp 而不是之前的 HTTPConnection 实现,或者至少在官方更新的 Nexus 设备上是这样的。

【讨论】:

您是如何确定这一点的?我查看了源码,发现okhttp库已经在源码since 4.2中了。 android.googlesource.com/platform/external/okhttp/+log 在2231db3 中实现的更改在Android 4.3 中不存在(不管标签上说什么);它们确实存在于 Android 4.4 中。 啊,好吧。我仍然很好奇为什么 AsyncTask 中的行为与单独线程中的行为不同。【参考方案2】:

这可能与persistent connections有关,并且HttpURLConnection试图重用相同的HTTP连接,因此在关闭连接或InputStream时,它试图通过读取并丢弃它们来消耗所有剩余的数据。然后相同的 HTTP 连接就可以为下一个命令做好准备了。

KitKat 中似乎有一些新的实现使事情变得不同并导致问题。

我尝试通过 HTTP 流式传输视频数据,偶尔搜索会导致关闭连接并启动新连接。当然,在这种情况下,我不需要一直提取视频流。

我试着打电话

HttpURLConnection con;
con.setRequestProperty("Connection", "close");

但这并没有什么不同。

但是,我尝试使用与 DefaultHttpClient 相同的代码并调用

HttpGet get = new HttpGet(uri);
get.addHeader("Connection", "close");

然后最终关闭连接的 InputStream 很快,我在调试器中通过进入 ConnectionReuseStrategy.keepAlive 并看到服务器返回 Connection:close 和 DefaultHttpClient 并没有尝试重用连接和读取直到结束来证明这一点。

因此您可以使用 DefaultHttpClient 或找到一种方法使 HttpURLConnection 仅关闭连接而无需读取休息。

【讨论】:

【参考方案3】:

你为什么不尝试使用 apache lib http 连接

类似这样的东西,在你的异步任务中

    HttpClient httpclient = new DefaultHttpClient();
    HttpPost httppost = new HttpPost("http://server.com");
    HttpResponse response = httpclient.execute(httppost);
    if(response!=null)
    
        final  String responseBody =EntityUtils.toString(response.getEntity());
        if (responseBody != null) 
          



        

    

【讨论】:

这在几年前被默默地弃用了,谷歌建议使用 HttpURLConnection。看到这个blog post。 我知道有几个用于 Android 的最新 Apache 东西的端口,但我觉得原始的 Java 东西应该可以工作。 嗨,克里斯,谢谢你的信息,我知道,谷歌不支持它,虽然效果很好,但通常我更喜欢使用 apache 库,因为它比标准的 java http 连接更快。也不需要 while readline 编码部分。网页直接作为字符串返回。就我而言,它效果很好,我强烈推荐它。 我测试过,使用 HttpClient 并关闭响应的 InputStream 会在我的设备上产生同样长的延迟(15 秒)。 borg666:正确格式化您的代码示例! @PointerNull,我们这里不接单,下次一定要好心问,你不在酒吧。

以上是关于Android KitKat HttpURLConnection 断开 AsyncTask的主要内容,如果未能解决你的问题,请参考以下文章

Android 4.4 KitKat 随机崩溃

Android 4.4系统 KitKat到底都有哪些能耐

KitKat 中的 Textinputlayout 膨胀异常

Android 5.0 材料设计风格的 KitKat 导航抽屉

无法在 Android 4.4 KitKat 上快速关闭 ChunkedInputStream

Android Studio 项目适用于 Lollipop,但不适用于 Kitkat