我有一个使用Twitter4j的流实现显示推文流的Android Daydream。在Android 4.2和4.3上运行良好。但是在4.4上,我无法快速关闭流(在
我得到了这个堆栈跟踪,但
问题似乎与此问题有关,涉及连接重用。 这个OkHttp更改集(在此处合并到Android)更改了
我现在得到
问题是流未在设置的超时时间内被丢弃。查看源代码最新版本的
这不是一个很大的问题 - 因为我现在必须在UI线程上关闭这个流,所以我不会导致
我已经测试了两个Twitter账户的流关闭时间,这两个账户的活动水平有所不同。第一个账户在我尝试关闭流的时间内没有看到任何活动,我一直看到调用需要约30秒。第二个账户上的活动要多得多,关闭流的时间在这个账户上变化很大 - 从1.5秒到30秒不等。当新推文进来时(一个新块被写入流中),它似乎会立即关闭。 为什么在KitKat上关闭流时会出现延迟?为什么它不遵守设置的100ms超时? 这类似于Android KitKat HttpURLConnection disconnect AsyncTask - 虽然那里可能使用了底层的
onDreamingStopped
)。我得到了这个堆栈跟踪,但
NetworkOnMainThreadException
不是问题所在。问题似乎与此问题有关,涉及连接重用。 这个OkHttp更改集(在此处合并到Android)更改了
close
在ChunkedInputStream
上的行为。现在,它不仅将自己标记为“关闭”,然后在仍有更多数据需要读取时断开套接字,而且还尝试首先丢弃流以便快速重用套接字。如果无法丢弃流,则像以前一样断开套接字。我现在得到
NetworkOnMainThreadException
的原因是因为(从堆栈跟踪中可以看出)丢弃流现在尝试从流中读取。这很容易解决-当关闭我的Daydream并忘记它时,我只需将其放入AsyncTask
中即可。问题是流未在设置的超时时间内被丢弃。查看源代码最新版本的
HttpTransport#discardStream
方法,它对套接字指定了100ms的超时时间(原始提交指定了30ms),然后尝试从流中读取(Util.skipAll
)以清空缓冲区。但我看到大约在BufferedInputStream.read()
中存在多秒延迟。此延迟的长度似乎有所不同。这不是一个很大的问题 - 因为我现在必须在UI线程上关闭这个流,所以我不会导致
onDreamingStopped
调用需要很长时间才能返回(这导致了Daydream在按下back/home后仍停留在屏幕上很长时间 - 这是我最初报告的错误,导致我跟着这个兔子洞)。但是,在它应该被关闭之后,它确实会让这个连接挂起一段时间。我已经测试了两个Twitter账户的流关闭时间,这两个账户的活动水平有所不同。第一个账户在我尝试关闭流的时间内没有看到任何活动,我一直看到调用需要约30秒。第二个账户上的活动要多得多,关闭流的时间在这个账户上变化很大 - 从1.5秒到30秒不等。当新推文进来时(一个新块被写入流中),它似乎会立即关闭。 为什么在KitKat上关闭流时会出现延迟?为什么它不遵守设置的100ms超时? 这类似于Android KitKat HttpURLConnection disconnect AsyncTask - 虽然那里可能使用了底层的
FixedLengthInputStream
,但是相同的更改已经应用于该类的close
方法。
BufferedInputStream.read
调用上。 - Adam SBufferedInputStream.read
调用上。在调试器中按下暂停按钮时,它正在尝试关闭,这是堆栈跟踪。 - Adam S