天天看點

從源碼角度分析Android系統的異常捕獲機制是如何運作的

我們在開發的時候經常會遇到各種異常,當程式遇到異常,便會将異常資訊抛到LogCat中,那這個過程是怎麼實作的呢?

我們以一個例子開始:

這個程式一啟動便會抛一個異常到Logcat中,就像這樣:

好,異常資訊就會通過Logcat輸出出來,接下來我們一起看一下它内部的工作原理:

首先:

我們知道通常我們在處理全局自定義異常的時候通常會這麼寫:

通過這樣的方式,我們便可以使程式在遇到異常的時候回調我們的對象執行個體,然後調用我們的uncaughtException方法。

我們知道,如果我們不這麼設定,系統是會自己處理異常的,那就一定有一個預設的異常處理對象,沒錯:

通過這個方法會傳回一個系統預設的UncaughtExceptionHandler對象,那麼這個對象是在哪被設定進去的呢?我們從源代碼裡面找答案:

咱們從Java最基礎層面看起,

我們的JAVA入口是:com.android.internal.os.RuntimeInit類的main方法,至于main方法在哪被調用,我們以後再讨論:

我們關注的是commonInit方法:

在我們代碼的第二行看到:Thread.setDefaultUncaughtExceptionHandler(new UncaughtHandler());那這個UncaughtHandler類在哪被定義呢?我們還可以在RuntimeInit.java中找到答案:

我們看到代碼中使用StringBuilder的message對象對基本資訊進行了組合,然後調用Clog_e方法,Clog_e方法通過

Log.println_native(Log.LOG_ID_CRASH, Log.ERROR, tag,msg + '\n' + Log.getStackTraceString(tr));将Log日志輸出到控制台。

接下來會調用

方法将我們的崩潰的Dialog顯示出來,就像這樣:

從源碼角度分析Android系統的異常捕獲機制是如何運作的

最終它還會将我們的程式殺死退出:

好這就是系統為我們提供的預設異常處理方法,接下來當然還有不少疑問:

1.RuntimeInit類的main方法是在哪被調用的。

2.throw new NullPointerException();這部分是怎麼執行的。

3.Thread的defaultUncaughtHandler屬性又是在哪被調用的。

4.等等

歡迎對這方面有興趣的可以在評論區參與讨論,也有可能是我學的還太少。

繼續閱讀