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

Ada*_*m S 4 java android okhttp

我有一个Android Daydream,使用Twitter4j的流媒体实现显示一连串的推文.这适用于Android 4.2和4.3.但是在4.4上,我无法快速关闭流(in onDreamingStopped).

我得到这个堆栈跟踪,NetworkOnMainThreadException不是问题.

连接重用问题似乎与此问题有关.这个OkHttp变更集(在这里合并到Android中)改变了close行为方式ChunkedInputStream.如果还有更多数据需要读取,它现在会尝试丢弃流,而不是简单地将自己标记为"已关闭"然后断开套接字,以便能够快速重用套接字.如果它无法丢弃流,则会像以前一样断开套接字.

我现在得到a的原因NetworkOnMainThreadException是因为(从堆栈跟踪中看到)丢弃流现在尝试从流中读取.这很容易解决 - 我只是AsyncTask在关闭我的白日梦时放弃它并忘掉它.

问题是在超时集内没有丢弃流.查看HttpTransport#discardStream最新版本源的方法,它指定套接字上的100ms超时(原始提交指定30ms),然后尝试从stream(Util.skipAll)读取以清空缓冲区.但是我看到BufferedInputStream.read()呼叫周围有多秒钟的延迟.这种延迟的长度似乎有所不同.

这不是一个大问题 - 因为我现在必须从UI线程关闭此流,我不会导致onDreamingStopped调用需要很长时间才能返回(这导致白日梦停留在屏幕上很长时间按下/回家后的时间 - 我最初的错误报告导致我跟随这个兔子洞.但是,它确实会在关闭之后将此连接暂停一段时间.

我已经测试了使用两个不同活动级别的Twitter帐户关闭流所需的时间.第一个在我试图关闭流时没有看到任何活动,我一直看到通话大约需要30秒.第二个帐户有更多的活动,关闭流的时间在这个上更加多变 - 从1.5到30秒不等.当一条新的推文进入时,它会立即关闭(一个新的块被写入流中).

为什么我在关闭KitKat的流时遇到这种延迟?为什么它不尊重正在设置的100ms超时?

这类似于Android KitKat HttpURLConnection断开AsyncTask - 虽然这可能是FixedLengthInputStream在引擎盖下使用,但同样的更改已应用于close该类的方法.

Jes*_*son 5

这是OkHttp中的一个错误.修复就在这里.如果您不介意在应用程序中包含OkHttp jar,则可以解决此问题,直到更新AOSP以包含此修复程序.

OkHttpClient okHttpClient = new OkHttpClient();
URL.setURLStreamHandlerFactory(okHttpClient);
Run Code Online (Sandbox Code Playgroud)

OkHttp 1.3没有及时合并修复程序; 你需要等待以后的发布或jar自己建立.