Java和Android崩溃捕获机制
引言
作为开发同学,每天都在面临各种各种的崩溃问题。
我们都如果在Android应用中发生了未捕获的崩溃问题,不管是在主线程还是在子线程,应用都会直接退出。
但是Java程序,子线程抛出的异常,不会引起程序的退出。
那你们知道JVM是如何处理应用未捕获崩溃的吗?Android又是怎样在发生崩溃时让程序退出的呢?
崩溃处理机制
当一个线程抛出异常时,JVM会调用线程的dispatchUncaughtException方法,所有未被捕获的异常,最后都会交给UncaughtExceptionHandler处理。
对于一个线程来说,UncaughtExceptionHandler有多个,首先有针对单个线程的unCaughtExceptionHandler,然后还有静态的首先有一个静态的defaultUncaughtExceptionHandler和defaultUncaughtPreExceptionHandler,这个是对每个线程都生效的。
处理顺序:未捕获的异常,先由线程处理,然后由线程的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崩溃捕获的资料请关注脚本之家其它相关文章!
相关文章
spring boot整合mybatis利用Mysql实现主键UUID的方法
这篇文章主要给大家介绍了关于spring boot整合mybatis利用Mysql实现主键UUID的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧。2018-03-03
使用Spring Data Jpa的CriteriaQuery一个陷阱
使用Spring Data Jpa的CriteriaQuery进行动态条件查询时,可能会遇到一个陷阱,当条件为空时,查询不到任何结果,并不是期望的返回所有结果。这是为什么呢?2020-11-11
完美解决springboot项目出现”java: 错误: 无效的源发行版:17“问题(图文详解)
这篇文章主要介绍了完美解决springboot项目出现”java: 错误: 无效的源发行版:17“问题,本文通过图文并茂的形式给大家介绍的非常详细,需要的朋友可以参考下2023-04-04
mapstruct的用法之qualifiedByName示例详解
qualifiedByName的意思就是使用这个Mapper接口中的指定的默认方法去处理这个属性的转换,而不是简单的get set,今天通过本文给大家介绍下mapstruct的用法之qualifiedByName示例详解,感兴趣的朋友一起看看吧2022-04-04
Java多线程中ReentrantLock与Condition详解
这篇文章主要介绍了Java多线程中ReentrantLock与Condition详解,需要的朋友可以参考下2017-11-11
java8 对象转Map时重复 key Duplicate key xxxx的解决
这篇文章主要介绍了java8 对象转Map时重复 key Duplicate key xxxx的解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教2021-09-09


最新评论