I have an Android Daydream that displays a stream of tweets using the streaming implementation of Twitter4j. This works great on Android 4.2 and 4.3. However, in 4.4 I canβt quickly close the stream (in onDreamingStopped ).
I get this stack trace , but NetworkOnMainThreadException not a problem.
The problem seems to be related to this problem due to reusing the connection. This OkHttp change set (which integrates in Android here ) changes the way close behaves on a ChunkedInputStream . Instead of simply labeling itself as βclosedβ and then disconnecting the socket if more data has been read, it now tries to first drop the stream to allow for quick reuse of the socket. If it does not delete the stream, it disables the socket, as before.
The reason I now get a NetworkOnMainThreadException is because (as you can see from the stack trace), dropping the thread is now trying to read from the thread. This is easy enough to fix - I just throw it at AsyncTask when I close my Dream and forget about it.
The problem is that the stream is not discarded during the timeout. Considering the HttpTransport#discardStream latest version of the source , it sets the timeout to 100 ms on the socket (the initial commit is 30 ms), then tries to read from the stream ( Util.skipAll ) to clear the buffer. However, I am observing a multi-second delay around the call to BufferedInputStream.read() . The length of this delay seems to be changing.
This is not a huge problem - since now I need to close this thread from the user interface thread, I do not call onDreamingStopped to take a long time (which made the dream stay on the screen for a long time after pressing back / home - my initial error report that made me follow this rabbit hole). However, it leaves this connection hanging for a while after it should be closed.
I tested how long it takes to close a stream with two Twitter accounts with different levels of activity. The first did not see any activity at the time when I was trying to close the stream, and I constantly watched that the call took about 30 seconds. The second account has much more activity, and the closing time of the stream was much more diverse on this - from 1.5 to 30 seconds. It seems that it instantly closes when a new tweet arrives (a new fragment is written to the stream).
Why do I see this delay when closing a thread on KitKat? Why does this not correspond to the set timeout of 100 ms?
This is similar to the Android KitKat HttpURLConnection disabling AsyncTask - although, presumably using the FixedLengthInputStream under the hood, the same change was applied to the close method of this class.
Adam s
source share