无法在Android 4.4奇巧迅速关闭ChunkedInputStream [英] Unable to close ChunkedInputStream quickly on Android 4.4 KitKat

查看:273
本文介绍了无法在Android 4.4奇巧迅速关闭ChunkedInputStream的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Android的白日梦,显示使用Twitter4j的流媒体实现的鸣叫流。这工作正常,在Android 4.2和4.3。在4.4然而,我不能迅速关闭流( onDreamingStopped )。

I've got an Android Daydream that displays a stream of tweets using Twitter4j's streaming implementation. This works fine on Android 4.2 and 4.3. On 4.4 however, I cannot quickly close the stream (in onDreamingStopped).

我收到这个堆栈跟踪 NetworkOnMainThreadException 是没有问题的。

I'm getting this stacktrace but the NetworkOnMainThreadException isn't the problem.

这个问题似乎是与这个问题,左右连接重用。 <一href="https://github.com/square/okhttp/commit/04d742bd3d6ce8ad24b21f2be2d6f3ea5f8a35a5#diff-d50d214c3607bcfa12dfcd5ef1abed85"相对=nofollow>这OkHttp变更(这被合并到Android的<一个href="https://android.googlesource.com/platform/external/okhttp/+/2231db3e6bb54447a9b14cf004a6cb03c373651c"相对=nofollow>这里)改变了方式,关闭行为的 ChunkedInputStream 。而不是简单地标记本身作为封闭,然后断开插座,如果有进一步的数据被读出,现在尝试首先丢弃该流,以使插座的快速重复利用。如果它不能丢弃流,它然后断开插座和以前一样。

The problem appears to be related to this issue, around connection reuse. This OkHttp changeset (which gets merged into Android here) changes the way that close behaves on ChunkedInputStream. Instead of simply marking itself as "closed" and then disconnecting the socket if there was still more data to be read, it now attempts to discard the stream first to enable quick reuse of the socket. If it fails to discard the stream, it then disconnects the socket as before.

的原因,我现在得到一个 NetworkOnMainThreadException 是因为(当你从堆栈跟踪看)丢弃流现在试图从流中读取。这是很容易修复 - 我只是把它在一个的AsyncTask 结束我的白日梦时,忘掉它

The reason I'm now getting a NetworkOnMainThreadException is because (as you see from the stack trace) discarding the stream now attempts to read from the stream. That's easy enough to fix - I just drop it in an AsyncTask when closing my Daydream and forget about it.

的问题是,该流不被超时集内丢弃。纵观<一href="https://android.googlesource.com/platform/external/okhttp/+/master/okhttp/src/main/java/com/squareup/okhttp/internal/http/HttpTransport.java"相对=nofollow> HttpTransport#discardStream 来源最新版本的方法,它规定了插座100ms的超时(原提交指定的30毫秒) ,然后尝试从流中读取( Util.skipAll )清空缓冲区。但是我看到周围的<一个多秒的延迟href="https://android.googlesource.com/platform/libcore/+/master/luni/src/main/java/java/io/BufferedInputStream.java"相对=nofollow> BufferedInputStream.read() 调用。该延迟的长度似乎各不相同。

The problem is that the stream isn't being discarded within the timeout set. Looking at the HttpTransport#discardStream method of the latest version of the source, it specifies a 100ms timeout on the socket (the original commit specified 30ms), then tries to read from the stream (Util.skipAll) to empty the buffer. However I'm seeing a multiple-second delay around the BufferedInputStream.read() call. The length of this delay seems to vary.

这是不是一个巨大的问题 - 因为我现在仍要关闭此流过的UI线程,我不会引起 onDreamingStopped 调用需要很长时间回(这是引起遐想留在屏幕上后,pressing BACK / HOME很长一段时间 - 我这引起了我遵循这个兔子洞初始错误报告)。但是,它不会离开这个连接挂一段时间了,它应该后关闭。

This isn't a huge problem - since I now have to close this stream off the UI thread anyway, I'm not causing the onDreamingStopped call to take a long time to return (which was causing the daydream to stay on the screen for a long time after pressing back/home - my initial bug report which caused me to follow this rabbit hole). However, it does leave this connection hanging around for a while after it's supposed to be closed.

我测试过它需要多长时间来与不同活动水平两个Twitter账户关闭流。第一个没有看到任何时间的活动,我试图关闭流,而我一直看到通话大约需要30秒。第二帐户上有更多的活动,时间以关闭该流是变化较多在这一个 - 从1.5到30秒的任何地方。它似乎关闭瞬间当一个新的鸣叫进来(新块被写入流)。

I've tested how long it takes to close the stream with two Twitter accounts of varying activity levels. The first one didn't see any activity in the time I was trying to close the stream, and I was consistently seeing the call take around 30 seconds. The second account has much more activity on it, and the time to close the stream was much more varied on this one - anywhere from 1.5 to 30 seconds. It appears to close instantly when a new tweet comes in (a new chunk is written to the stream).

为何会出现这种延迟在奇巧关闭流?它为何不尊重这一点正在被设置为100ms超时?

这是类似于<一href="http://stackoverflow.com/questions/20104404/android-kitkat-httpurlconnection-disconnect-asynctask">Android奇巧的HttpURLConnection断开的AsyncTask - 尽管这psumably使用 FixedLengthInputStream 引擎盖下,同样的变化已经被应用到接近$ P $ 该类的方法。

This is similar to Android KitKat HttpURLConnection disconnect AsyncTask - although that's presumably using a FixedLengthInputStream under the hood, the same change has been applied to the close method of that class.

推荐答案

这是OkHttp的错误。修复是这里。如果你不介意的话,包括在应用程序中OkHttp罐子,你可以工作,解决这个问题,直到AOSP的更新,包括修复。

This was a bug in OkHttp. Fix is here. If you don't mind including the OkHttp jar in your application, you can work-around this problem until AOSP is updated to include the fix.

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

此修复程序并没有合并的时间OkHttp 1.3;你需要等待以后的版本或建立自己。

这篇关于无法在Android 4.4奇巧迅速关闭ChunkedInputStream的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆