你們都知道,如今安裝Android系統的手機版本和設備千差萬別,在模擬器上運行良好的程序安裝到某款手機上說不定就出現崩潰的現象,開發者我的不可能購買全部設備逐個調試,因此在程序發佈出去以後,若是出現了崩潰現象,開發者應該及時獲取在該設備上致使崩潰的信息,這對於下一個版本的bug修復幫助極大,因此今天就來介紹一下如何在程序崩潰的狀況下收集相關的設備參數信息和具體的異常信息,併發送這些信息到服務器供開發者分析和調試程序。html
咱們先創建一個crash項目,項目結構如圖:java
在MainActivity.java代碼中,代碼是這樣寫的:android
咱們在這裏故意製造了一個潛在的運行期異常,當咱們運行程序時就會出現如下界面:服務器
遇到軟件沒有捕獲的異常以後,系統會彈出這個默認的強制關閉對話框。網絡
咱們固然不但願用戶看到這種現象,簡直是對用戶心靈上的打擊,並且對咱們的bug的修復也是毫無幫助的。咱們須要的是軟件有一個全局的異常捕獲器,當出現一個咱們沒有發現的異常時,捕獲這個異常,而且將異常信息記錄下來,上傳到服務器公開發這分析出現異常的具體緣由。併發
接下來咱們就來實現這一機制,不過首先咱們仍是來了解如下兩個類:android.app.Application和java.lang.Thread.UncaughtExceptionHandler。app
Application:用來管理應用程序的全局狀態。在應用程序啓動時Application會首先建立,而後纔會根據狀況(Intent)來啓動相應的Activity和Service。本示例中將在自定義增強版的Application中註冊未捕獲異常處理器。編輯器
Thread.UncaughtExceptionHandler:線程未捕獲異常處理器,用來處理未捕獲異常。若是程序出現了未捕獲異常,默認會彈出系統中強制關閉對話框。咱們須要實現此接口,並註冊爲程序中默認未捕獲異常處理。這樣當未捕獲異常發生時,就能夠作一些個性化的異常處理操做。ide
你們剛纔在項目的結構圖中看到的CrashHandler.java實現了Thread.UncaughtExceptionHandler,使咱們用來處理未捕獲異常的主要成員,代碼以下:函數
在收集異常信息時,朋友們也可使用Properties,由於Properties有一個很便捷的方法properties.store(OutputStream out, String comments),用來將Properties實例中的鍵值對外輸到輸出流中,可是在使用的過程當中發現生成的文件中異常信息打印在同一行,看起來極爲費勁,因此換成Map來存放這些信息,而後生成文件時稍加了些操做。
完成這個CrashHandler後,咱們須要在一個Application環境中讓其運行,爲此,咱們繼承android.app.Application,添加本身的代碼,CrashApplication.java代碼以下:
最後,爲了讓咱們的CrashApplication取代android.app.Application的地位,在咱們的代碼中生效,咱們須要修改AndroidManifest.xml:
由於咱們上面的CrashHandler中,遇到異常後要保存設備參數和具體異常信息到SDCARD,因此咱們須要在AndroidManifest.xml中加入讀寫SDCARD權限:
搞定了上邊的步驟以後,咱們來運行一下這個項目:
看以看到,並不會有強制關閉的對話框出現了,取而代之的是咱們比較有好的提示信息。
而後看一下SDCARD生成的文件:
用文本編輯器打開日誌文件,看一段日誌信息:
這些信息對於開發者來講幫助極大,因此咱們須要將此日誌文件上傳到服務器,有關文件上傳的技術,請參照Android中使用HTTP服務相關介紹。
不過在使用HTTP服務以前,須要肯定網絡暢通,咱們可使用下面的方式判斷網絡是否可用: