我正在使用HTTPClient库,我遇到一个奇怪的问题,即Socket.close()调用永远不会返回,导致TimeoutException。偶尔会发生这种情况,我可以在大约10%的时间内重现它。
我在Android 4.2,4.3和4.4上看到了这个问题。
以下是我为此问题创建的Android Bug Ticket:
http://code.google.com/p/android/issues/detail?id=66102
为什么Socket.close会永远挂起来?我怎么能避免这个?谢谢!
02-17 20:48:31.800: E/AndroidRuntime(12871): FATAL EXCEPTION: FinalizerWatchdogDaemon
02-17 20:48:31.800: E/AndroidRuntime(12871): Process: com.vblast.sample, PID: 12871
02-17 20:48:31.800: E/AndroidRuntime(12871): java.util.concurrent.TimeoutException: org.apache.http.impl.conn.PoolingHttpClientConnectionManager.finalize() timed out after 10 seconds
02-17 20:48:31.800: E/AndroidRuntime(12871): at libcore.io.Posix.close(Native Method)
02-17 20:48:31.800: E/AndroidRuntime(12871): at libcore.io.BlockGuardOs.close(BlockGuardOs.java:75)
02-17 20:48:31.800: E/AndroidRuntime(12871): at libcore.io.IoBridge.closeSocket(IoBridge.java:188)
02-17 20:48:31.800: E/AndroidRuntime(12871): at java.net.PlainSocketImpl.close(PlainSocketImpl.java:162)
02-17 20:48:31.800: E/AndroidRuntime(12871): at java.net.Socket.close(Socket.java:317)
02-17 20:48:31.800: E/AndroidRuntime(12871): at org.apache.http.impl.BHttpConnectionBase.close(BHttpConnectionBase.java:346)
02-17 20:48:31.800: E/AndroidRuntime(12871): at org.apache.http.impl.conn.LoggingManagedHttpClientConnection.close(LoggingManagedHttpClientConnection.java:83)
02-17 20:48:31.800: E/AndroidRuntime(12871): at org.apache.http.impl.conn.CPoolEntry.closeConnection(CPoolEntry.java:70)
02-17 20:48:31.800: E/AndroidRuntime(12871): at org.apache.http.impl.conn.CPoolEntry.close(CPoolEntry.java:96)
02-17 20:48:31.800: E/AndroidRuntime(12871): at org.apache.http.pool.AbstractConnPool.shutdown(AbstractConnPool.java:127)
02-17 20:48:31.800: E/AndroidRuntime(12871): at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.shutdown(PoolingHttpClientConnectionManager.java:347)
02-17 20:48:31.800: E/AndroidRuntime(12871): at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.finalize(PoolingHttpClientConnectionManager.java:168)
02-17 20:48:31.800: E/AndroidRuntime(12871): at java.lang.Daemons$FinalizerDaemon.doFinalize(Daemons.java:187)
02-17 20:48:31.800: E/AndroidRuntime(12871): at java.lang.Daemons$FinalizerDaemon.run(Daemons.java:170)
02-17 20:48:31.800: E/AndroidRuntime(12871): at java.lang.Thread.run(Thread.java:841)
答案 0 :(得分:2)
原来我混淆使用Socket.setSoLinger()
作为我的连接超时设置导致长时间挂起,从而导致TimeoutException。 :/
这是Socket.setSoLinger()
的作用:
如果套接字处于连接模式,则设置SO_LINGER选项 对于具有非零逗留时间的套接字,并且套接字具有 未发送的数据,则close()将阻塞直到当前 延迟间隔,直到所有数据都被传输。
http://pubs.opengroup.org/onlinepubs/009695399/functions/close.html
答案 1 :(得分:0)
这里真正的问题是你泄漏了连接,要求它在完成时关闭。您需要检查代码以确保关闭在finally块中。您可能还必须自己调用HttpURLConnection.disconnect()。