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 之前的设备中,它需要一毫秒或更短的时间。真正奇怪的是,当我在单独的线程上执行断开调用时,它又真的很快了。所以在AsyncTask
的doInBackground
方法中调用它一定是个问题。需要注意的一件事是我的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的主要内容,如果未能解决你的问题,请参考以下文章
KitKat 中的 Textinputlayout 膨胀异常
Android 5.0 材料设计风格的 KitKat 导航抽屉