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

2024-06-28

我有一个 Android Daydream,它使用 Twitter4j 的流实现来显示推文流。这在 Android 4.2 和 4.3 上运行良好。然而,在 4.4 上,我无法快速关闭流(在onDreamingStopped).

我越来越这个堆栈跟踪 https://gist.github.com/adamsp/019ab66bf43489927332但是NetworkOnMainThreadException这不是问题。

该问题似乎与这个问题 https://code.google.com/p/android/issues/detail?id=38817,围绕连接重用。这个 OkHttp 变更集 https://github.com/square/okhttp/commit/04d742bd3d6ce8ad24b21f2be2d6f3ea5f8a35a5#diff-d50d214c3607bcfa12dfcd5ef1abed85(它被合并到Android中here https://android.googlesource.com/platform/external/okhttp/+/2231db3e6bb54447a9b14cf004a6cb03c373651c)改变了方式close表现在ChunkedInputStream。现在,它不再简单地将自身标记为“已关闭”,然后在仍有更多数据需要读取时断开套接字,而是首先尝试丢弃流以实现套接字的快速重用。如果无法丢弃流,则会像以前一样断开套接字。

我现在得到的原因是NetworkOnMainThreadException是因为(正如您从堆栈跟踪中看到的)丢弃流现在尝试从流中读取。这很容易修复 - 我只需将其放入AsyncTask当关闭我的白日梦并忘记它时。

问题是流在超时设置内没有被丢弃。看着HttpTransport#discardStream最新版本源码的方法 https://android.googlesource.com/platform/external/okhttp/+/master/okhttp/src/main/java/com/squareup/okhttp/internal/http/HttpTransport.java,它在套接字上指定 100ms 超时(原始提交指定 30ms),然后尝试从流中读取(Util.skipAll) 清空缓冲区。但是我发现有几秒的延迟BufferedInputStream.read() https://android.googlesource.com/platform/libcore/+/master/luni/src/main/java/java/io/BufferedInputStream.java称呼。这种延迟的长度似乎有所不同。

这不是一个大问题 - 因为我现在必须从 UI 线程关闭这个流,所以我不会导致onDreamingStopped调用需要很长时间才能返回(这导致白日梦在按返回/主页后在屏幕上停留很长时间 - 我最初的错误报告导致我跟踪这个兔子洞)。然而,在应该关闭的连接之后,它确实会让这个连接挂起一段时间。

我测试了使用两个不同活动级别的 Twitter 帐户关闭流所需的时间。第一个在我尝试关闭流时没有看到任何活动,并且我一直看到调用需要大约 30 秒。第二个帐户上的活动要多得多,并且关闭流的时间在这个帐户上变化得多 - 从 1.5 秒到 30 秒不等。当新的推文进入时(新的块被写入流中),它似乎立即关闭。

为什么我在 KitKat 上关闭流时会出现延迟?为什么它不遵守所设置的 100 毫秒超时?

这类似于Android KitKat HttpURLConnection 断开 AsyncTask https://stackoverflow.com/questions/20104404/android-kitkat-httpurlconnection-disconnect-asynctask- 虽然这大概是使用FixedLengthInputStream在幕后,同样的变化也适用于close该类的方法。


这是 OkHttp 中的一个错误。修复是here https://github.com/square/okhttp/pull/430。如果您不介意在应用程序中包含 OkHttp jar,则可以解决此问题,直到 AOSP 更新以包含修复程序。

OkHttpClient okHttpClient = new OkHttpClient();
URL.setURLStreamHandlerFactory(okHttpClient);

该修复未及时合并到 OkHttp 1.3;您需要等待稍后的版本或构建jar你自己。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

无法在 Android 4.4 KitKat 上快速关闭 ChunkedInputStream 的相关文章

随机推荐