崩溃优化之Java层crash原理分析-创新互联

一、造成系统崩溃(crash)的原因是什么? 未捕获的异常

有Java层面,和Native层面。

成都创新互联公司服务项目包括循化网站建设、循化网站制作、循化网页制作以及循化网络营销策划等。多年来,我们专注于互联网行业,利用自身积累的技术优势、行业经验、深度合作伙伴关系等,向广大中小型企业、政府机构等提供互联网行业的解决方案,循化网站推广取得了明显的社会效益与经济效益。目前,我们服务的客户以成都为中心已经辐射到循化省份的部分城市,未来相信会继续扩大服务区域并继续获得客户的支持与信任!

在我们平常操作中,如果有未捕获的异常,会导致系统崩溃,这个崩溃本质上是人为操作的,人为去操作系统主动退出(后面讲源码的地方可以看到)。

ANR

系统因为线程阻塞问题,导致的无响应。

WTF(What a Terrible Failure)

一般指,系统中自己编码没有按照android要求进行,例如发送未受保护的广播、启动的Activity未在注册文件里注册等等;

这个一般不用太关注,主要写代码按标准来就行。


二、java层未捕获的异常是如何导致崩溃的 源码分析步骤1

首先我们先明确一个目的,我们的main函数的启用本身作为主线程存在,那么在我们想要探索系统到底如何处理异常,需要去关注到一个类Thread;

在我们的程序代码中,如果存在一个异常,任何地方都没有去捕获处理它的话,它就会一路往上抛,最终来到main函数,如果main函数也没有处理这个异常,就会给到JVM来处理,JVM会给到当前的线程Thread来处理。

源码分析步骤2

在Thread类中,看到一段这样的函数dispatchUncaughtException();

注释翻译为:向处理程序发送未捕获的异常。此方法旨在仅由JVM调用;可以理解为,未处理的异常会走到这里来:

在上图我们可以看到官方明确告知,JVM在处理未经捕获的异常时,会调用当前dispatchUncaughtException函数进行处理,这个里面我们能看到一个类型为UncaughtExceptionHandler的类。

在上图的逻辑中我们可以看到如果没有设置uncaughtExceptionHandler,将使用线程所在的线程组(ThreadGroup)来处理这个未捕获异常。线程组ThreadGroup实现了UncaughtExceptionHandler,所以可以用来处理未捕获异常。

源码分析步骤3

所以,我们重点来看ThreadGroup中,是如何来处理未捕获异常的:在Thread类的dispatchUncaughtException函数中,最后调用了getUncaughtExceptionHandler().uncaughtException(this, e); 我们知道这个getUncaughtExceptionHandler()返回的是ThreadGroup,所以我们来看ThreadGroup中的uncaughtException方法:

默认情况下,ThreadGroup处理未捕获异常的逻辑是:

  1. 首先将异常消息通知给父线程组(如果parent不为空的话);

  1. 然后尝试利用一个默认的defaultUncaughtExceptionHandler来处理异常;

  1. 如果没有默认的异常处理器则将错误信息输出打印到System.err。

这里可以思考下,我们可以自定义一个异常处理类,继承下 Thread.UncaughtExceptionHandler,然后去处理未捕获的异常。记得需要手动去调用Thread.setUncaughtExceptionPreHandler()方法设置下,有了这个自定义异常处理类,就可以做相应的崩溃优化。

源码分析步骤4

回到Thread中,思考下:既然他是通过getDefaultUncaughtExceptionHandler来处理,现在我们并没有看到有相关的设置,但是在Thread中我们看到了他对外提供了对应的设置函数:Thread.setUncaughtExceptionPreHandler()。

源码分析步骤5

思考下:系统是否会有地方默认给我们设置了uncaughtExceptionHandler?

因为从上面的源码看来,我们并没有看到有让系统直接崩溃掉的情况,因为默认是ThreadGroup去处理,他只不过是做了一个日志信息的记录,不会有退出的情况,那么肯定是有哪个地方默认设置了uncaughtExceptionHandler,让系统退出的。

源码分析步骤6

来看下RuntimeInit这个类,zygote负责启动RuntimeInit进程(作用:app运行时环境初始化,用来初始化运行时的一系列信息,其中包含异常处理),它里面有个main方法:

这里设置了默认的异常处理:KillApplicationHandler。

源码分析步骤7

我们来看下KillApplicationHandler:

重点来看 uncaughtException(Thread t, Throwable e)这个方法:

看到这里就知道了,默认的异常处理(杀进程)是在RuntimeInit进程(作用:app运行时环境初始化,用来初始化运行时的一系列信息,其中包含异常处理)的main()方法里设置的。

小总结
三、AMS如何承接应用的异常信息上报?

在上面的源码分析步骤7我们知道了,在KillApplicationHandler的uncaughtException()方法里,最终异常信息有一个AMS上报过程:

来看下ActivityManagerService.handleApplicationCrash()方法:

从上面可以看出,若传入app为null时,processName就设置为system_server,意思是:如果没有来源默认判定是系统进程自己。接着看handleApplicationCrashInner(String eventType......)方法:

参数eventType是指事件类型,具体如下:

  • Java层未捕捉的异常:crash

  • ANR:anr

  • native层的异常:native_crash

现在我们看的是java的异常,所以这个类型传的是crash。

接着看handleApplicationCrashInner()函数:

中间的可以先不管他们,这个可以理解为在进行系统日志输出,具体的处理是在addErrorToDropBox()函数中。

重点注意:无论是java crash、native_crash、ANR或是wtf,最终都是来到这里,交由addErrorToDropBox()函数去处理。


四、DropBoxManager

addErrorToDropBox()函数和DropBoxManager有关,Android Dropbox 是 Android 在 Froyo(API level 8) 引入的用来持续化存储系统数据的机制。主要用于记录 Android 运行过程中, 内核, 系统进程, 用户进程等出现严重问题时的 log, 可以认为这是一个可持续存储的系统级别的 logcat。

记录位置:在data/system/dropbox中:

也就是说,我们想要看系统的崩溃日志,可以在这个文件路径下找。

你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧

当前题目:崩溃优化之Java层crash原理分析-创新互联
标题URL:https://www.cdcxhl.com/article48/cescep.html

成都网站建设公司_创新互联,为您提供定制开发网页设计公司网站制作软件开发云服务器网站策划

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联

成都定制网站建设