Thread starting during runtime shutdown問題的解決

注:本內容僅是工做筆記,用於備忘,未貼出具體代碼。描述不清請見諒。java

===================================================================================================apache

問題描述與分析:服務器

  爲了獲取Crash日誌,項目中實現了UncaughtExceptionHandler接口對未知異常進行捕獲並上傳到服務器中,同時中止App運行。在Android5.0如下系統一直未出現過問題,可是忽然發如今Android 5.0以上的機器中這段代碼出現了java.lang.InternalError: Thread starting during runtime shutdown(更多異常信息見最後部分的附錄),在stackoverflow中獲得了一些幫助:這個問題是由於線程開啓的太晚了!網絡

  何時開啓線程纔算得上「太晚了」呢? 在個人項目中UncaughtExceptionHandler實現類捕獲到異常時(也就是UncaughtExceptionHandler接口的uncaughtException方法執行時),開啓了一個線程用於上傳崩潰日誌,而在線程中上傳崩潰日誌時建立了HttpClient發送網絡請求。HttpClient建立時設置了ThreadSafeClientConnManager來管理鏈接,而在ThreadSafeClientConnManager的源碼中又一次開啓了線程!也就是說,uncaughtException方法執行時在開啓的線程中又開啓了新的線程,這樣可能會致使uncaughtException方法在執行完成時,「線程中的線程」才start(),而聽說uncaughtException方法執行完成後ART環境就shutdown了(uncaughtException方法結束時ART是否會真的shutdown,這一點有待考證,筆者也僅是從其餘非官方資料中得知),這種狀況下就會拋出java.lang.InternalError: Thread starting during runtime shutdown。線程

  爲了驗證這個問題,編寫了一段簡單的代碼:實現UncaughtExceptionHandler的uncaughtException方法,在uncaughtException方法中開啓一個線程,在這個線程中再開一線程,同時在MainActivity中故意製造一個異常發生,此時果真會出現java.lang.InternalError: Thread starting during runtime shutdown(並非每次都出現,由於若是uncaughtException方法執行結束以前,兩個線程都完成start(),此問題就不會出現)。日誌

 

解決方法:對象

  避免在uncaughtException方法中出現線程嵌套:針對個人項目,再也不去在線程中建立HttpClient(由於HttpClient建立時還會開啓線程,這就形成了線程中再次開啓線程),而是先建立HttpClient對象,再在線程中使用HttpClient對象。這樣就能夠確保uncaughtException方法結束以前HttpClient已經被建立,HttpClient中開啓線程也就不會有問題。接口

 

附異常信息:源碼

java.lang.InternalError: Thread starting during runtime shutdown at java.lang.Thread.nativeCreate(Native Method) at java.lang.Thread.start(Thread.java:1042) at org.apache.http.impl.conn.tsccm.AbstractConnPool.enableConnectionGC(AbstractConnPool.java:140) at org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager.createConnectionPool(ThreadSafeClientConnManager.java:120) at org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager.<init>(ThreadSafeClientConnManager.java:98) at it

相關文章
相關標籤/搜索