java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > Java Android崩溃捕获

Java和Android崩溃捕获机制

作者:尹学姐

这篇文章主要为大家介绍了Java和Android崩溃捕获机制详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

引言

作为开发同学,每天都在面临各种各种的崩溃问题。

我们都如果在Android应用中发生了未捕获的崩溃问题,不管是在主线程还是在子线程,应用都会直接退出。
但是Java程序,子线程抛出的异常,不会引起程序的退出。

那你们知道JVM是如何处理应用未捕获崩溃的吗?Android又是怎样在发生崩溃时让程序退出的呢?

崩溃处理机制

当一个线程抛出异常时,JVM会调用线程的dispatchUncaughtException方法,所有未被捕获的异常,最后都会交给UncaughtExceptionHandler处理。

对于一个线程来说,UncaughtExceptionHandler有多个,首先有针对单个线程的unCaughtExceptionHandler,然后还有静态的首先有一个静态的defaultUncaughtExceptionHandlerdefaultUncaughtPreExceptionHandler,这个是对每个线程都生效的。

处理顺序:未捕获的异常,先由线程处理,然后由线程的ThreadGroup处理,最后再由默认异常处理程序处理。

Android发生崩溃后

为什么Android发生异常后,不管是在主线程还是在子线程,都会引起程序crash退出呢?

其实是因为Android给所有线程都设置了一个defaultExceptionHandler,这个ExceptionHandler的处理逻辑就是让程序退出。

下面我们来看源码。

在应用程序被创建的时候,RuntimeInit会设置一个默认的异常处理Handler,这个异常处理Handler就是KillApplicationHandler。从名字就可以看出,这个Handler主要负责杀掉App进程。

// RuntimInit
protected static final void commonInit() {
    LoggingHandler loggingHandler = new LoggingHandler();
    // 设置preExceptionHandler
    Thread.setUncaughtExceptionPreHandler(loggingHandler);
    // KillApplicationHandler 作为全局 Handler
    Thread.setDefaultUncaughtExceptionHandler(new KillApplicationHandler(loggingHandler));
    //...
}

KillApplicationHandler会先调用loggingHandler打印日志,然后杀掉当前进程。

   private static class KillApplicationHandler implements Thread.UncaughtExceptionHandler {
        private final LoggingHandler mLoggingHandler;
        public KillApplicationHandler(LoggingHandler loggingHandler) {
            // 传入loggingHandler用于打日志
            this.mLoggingHandler = Objects.requireNonNull(loggingHandler);
        }
        @Override
        public void uncaughtException(Thread t, Throwable e) {
            try {
                // 打日志
                ensureLogging(t, e);
                // 已经在crash中了,不处理了
                if (mCrashing) return;
                mCrashing = true;
                // ...
            } catch (Throwable t2) {
                // ...
            } finally {
                // 通知内核杀掉进程
                Process.killProcess(Process.myPid());
                // 停止VM
                System.exit(10);
            }
        }

所以,当出现未捕获的异常时,会交给KillApplicationHandler中的uncaughtException,从而直接让程序退出。与此同时,我们也可以从adb日志中看到崩溃的具体堆栈。

下一篇,我们讲讲如何借用 uncaughtExceptionHandler的原理来实现Android应用永不崩溃。

以上就是Java和Android崩溃捕获机制的详细内容,更多关于Java Android崩溃捕获的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文