HttpClient的释放问题
生活随笔
收集整理的這篇文章主要介紹了
HttpClient的释放问题
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
最近遇到了這樣一個問題,在Android開啟StrictMode的時候,會拋出一個異常如下:
04-01 16:07:56.864: E/StrictMode(26867): A resource was acquired at attached stack trace but never released. See java.io.Closeable for information on avoiding resource leaks.?04-01 16:07:56.864: E/StrictMode(26867): java.lang.Throwable: Explicit termination method 'close' not called 04-01 16:07:56.864: E/StrictMode(26867): ????????at dalvik.system.CloseGuard.open(CloseGuard.java:184)?
04-01 16:07:56.864: E/StrictMode(26867): ????????at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:271)?
04-01 16:07:56.864: E/StrictMode(26867): ????????at com.android.org.conscrypt.OpenSSLSocketImpl.waitForHandshake(OpenSSLSocketImpl.java:598)?
04-01 16:07:56.864: E/StrictMode(26867): ????????at com.android.org.conscrypt.OpenSSLSocketImpl.getInputStream(OpenSSLSocketImpl.java:560)?
04-01 16:07:56.864: E/StrictMode(26867): ????????at org.apache.http.impl.io.SocketInputBuffer.(SocketInputBuffer.java:70)?
04-01 16:07:56.864: E/StrictMode(26867): ????????at org.apache.http.impl.SocketHttpClientConnection.createSessionInputBuffer(SocketHttpClientConnection.java:83)?
04-01 16:07:56.864: E/StrictMode(26867): ????????at org.apache.http.impl.conn.DefaultClientConnection.createSessionInputBuffer(DefaultClientConnection.java:170)?
04-01 16:07:56.864: E/StrictMode(26867): ????????at org.apache.http.impl.SocketHttpClientConnection.bind(SocketHttpClientConnection.java:106)?
04-01 16:07:56.864: E/StrictMode(26867): ????????at org.apache.http.impl.conn.DefaultClientConnection.openCompleted(DefaultClientConnection.java:129)?
04-01 16:07:56.864: E/StrictMode(26867): ????????at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:172)?
04-01 16:07:56.864: E/StrictMode(26867): ????????at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)?
04-01 16:07:56.864: E/StrictMode(26867): ????????at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)?
04-01 16:07:56.864: E/StrictMode(26867): ????????at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:360)?
04-01 16:07:56.864: E/StrictMode(26867): ????????at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555)?
04-01 16:07:56.864: E/StrictMode(26867): ????????at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)?
04-01 16:07:56.864: E/StrictMode(26867): ????????at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465) 異常大概是說資源沒有釋放,需要顯示的調用close方法。從log上看是網絡訪問時出現的問題(我使用的是HttpClient)。 但是在關閉StrictMode的時候程序可以完全正常的運行。原因何在呢? 通過查看HttpClient官方文檔發現,在HttpClient請求結束后需要銷毀HttpEntity,這樣才可以使網絡連接返回連接池等待下一次重用(如果不需要重用的話也可以直接關掉連接)。 官方推薦的HttpEntity銷毀方法:HttpEntity#consumeContent 在查看代碼時發現,HttpEntity并沒有銷毀。可是其他網絡請求部分的HttpEntity也都沒有銷毀,為什么只有這一個網絡請求會報錯呢?而且代碼中有監聽網絡超時并關掉連接的處理,為什么還會出現這個問題呢? 仔細查看發現,出現問題的部分與其他部分稍有不同。出現問題的網絡請求在解析響應的時候,并不需要解析Entity,他的響應結果是放在Headers里面的。也就是說這部分代碼在請求結束的時候沒有調用HttpResponse#getEntity#getContent方法。 查看HttpClient文檔發現getContent方法也可以使Entity銷毀。 所以就是這個原因使StrictMode拋出資源未釋放的異常。 因為有了網絡超時監聽的處理,所以在關閉StrictMode的時候并不會出現什么問題,因為沒有釋放的連接會等到網絡超時的時候會被釋放。 在使用HttpClient時一定要注意資源的釋放。即使有網絡超時自動關閉連接的監聽,StrictMode也會報告沒有釋放資源的異常,因為連接不會立即釋放,需要等待超時時間的到來才會release,這樣影響了程序的性能。 附HttpClient源碼分析: 1.BasicHttpEntity#getContent源碼: 在getContent方法中將contentObtained置為true;標記content已經被獲取過了,在其他地方檢測這個標記,如果資源被獲取過,那么就會release掉這個連接。 2.BasicHttpEntity#consumeContent源碼: 關閉content(content類型為InputStream) 3.EntityUtils#toString 在EntityUtils#toString方法的最后直接進行了reader.close();因此直接調用EntityUtils#toString方法后相當于調用了HttpEntity#consumeContent方法
轉載于:https://www.cnblogs.com/younghome/p/4609022.html
總結
以上是生活随笔為你收集整理的HttpClient的释放问题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: onkeyup,onkeydown和on
- 下一篇: 使用 Fluent API 配置/映射属