Java和Android崩溃捕获机制

 更新时间:2023年07月28日 10:32:09   作者:尹学姐  
这篇文章主要为大家介绍了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崩溃捕获的资料请关注脚本之家其它相关文章!

相关文章

  • java 出现Zipexception 异常的解决办法

    java 出现Zipexception 异常的解决办法

    这篇文章主要介绍了java 出现Zipexception 异常的解决办法的相关资料,出现 java.util.zip.ZipException: error in opening zip file 异常的原因及解决方法,需要的朋友可以参考下
    2017-08-08
  • SpringBoot中使用Redis对接口进行限流的实现

    SpringBoot中使用Redis对接口进行限流的实现

    本文将结合实例代码,介绍SpringBoot中使用Redis对接口进行限流的实现,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-07-07
  • java模拟http请求的错误问题整理

    java模拟http请求的错误问题整理

    本文是小编给大家整理的在用java模拟http请求的时候遇到的错误问题整理,以及相关分析,有兴趣的朋友参考下。
    2018-05-05
  • 使用eclipse创建java项目的方法

    使用eclipse创建java项目的方法

    这篇文章主要为大家详细介绍了使用eclipse创建java项目的方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-04-04
  • Mybatis使用collection标签进行树形结构数据查询时携带外部参数查询

    Mybatis使用collection标签进行树形结构数据查询时携带外部参数查询

    这篇文章主要介绍了Mybatis使用collection标签进行树形结构数据查询时携带外部参数查询,需要的朋友可以参考下
    2023-10-10
  • Java变量和对象的作用域

    Java变量和对象的作用域

    本文主要介绍了Java变量和对象的作用域的相关知识。具有很好的参考价值,下面跟着小编一起来看下吧
    2017-03-03
  • java服务端微信APP支付接口详解

    java服务端微信APP支付接口详解

    这篇文章主要为大家详细介绍了java服务端微信APP支付接口,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-04-04
  • Java类加载器层次结构原理解析

    Java类加载器层次结构原理解析

    这篇文章主要介绍了Java类加载器层次结构原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-06-06
  • Spring轻松解决循环依赖

    Spring轻松解决循环依赖

    Spring的解决循环依赖是有前置条件的,要解决循环依赖我们首先要了解Spring Bean对象的创建过程和依赖注入的方式。依赖注入方式,我之前的博客有所分享,大家可以在看本篇文章之前进行一下小小的回顾
    2023-04-04
  • Jenkins自动化部署SpringBoot项目的实现

    Jenkins自动化部署SpringBoot项目的实现

    本文主要介绍了Jenkins自动化部署SpringBoot项目的实现,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2023-01-01

最新评论