天天看点

从源码角度分析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.等等

欢迎对这方面有兴趣的可以在评论区参与讨论,也有可能是我学的还太少。

继续阅读