android应用,过高的Crash率影响用户的体验。降低Crash率对提升产品的功能和性能从而改善用户的体验具有重大的意义。
涉及层面:
Crash率涉及到各个层面包括各个BU的开发人员的代码质量,Android本身的系统问题,第三方的框架问题比如图片加载库等,armeabi兼容armeabi-v7和armeabi-v8以及新的arm体系结构的问题,Android硬件设备的硬件渲染的问题,兼容硬件渲染和webview兼容webkit/Blink的问题,引入新的框架和新的产品所带入的问题等等。
Crash率的降低是一个APP发展过程中必然的问题,也是需要长期关注和解决的问题。
1 Crash问题的总体分类
Android APP正式上线后,用户使用时会触发各种各样的Crash问题,这些问题通过腾讯的bugly系统被捕获,捕获的方式包括Java层面和C/C++层面。 Java层面借助于Android全局的异常捕捉方式比如Thread.setDefaultUncaughtExceptionHandler()等来实现,对于C/C++层面,则通过signal的捕捉来处理。
从大的分类来看,可以分为存量问题和新增问题。存量问题是已经发布的版本在用户使用时所暴露出的Crash问题;新增问题是在之前版本的基础上新写的代码和开发新的产品的特性所造成的Crash问题。
2 代码静态处理方式和工具
Crash暴露出首先需要加强代码的静态处理,包括
3 Crash分类归纳
Crash问题基于不同的发布版本有不同的分类,可以把Crash问题分类如下:
3.1 空指针问题
通常暴露出java.lang.NullPointerException(NPE)的Crash问题, 原因包括字符串变量未初始化;类对象没有做初始化;对象的值为空时,没有判断为空的情况等等。
3.2 越界问题
java.lang.IndexOutOfBoundsException和java.lang.ArrayIndexOutOfBoundsException
等数组或者索引越界问题,原因是列表,数组等集合类的对象的索引超出了范围,比如对象的size为空去索引值或者size不为空去索引超出范围的值。
3.3 类查找问题
java.lang.ClassNotFoundException
类存在但是所在的bundle未被加载或者类实际上不存在。
3.4 资源查找问题
android.content.res.Resources$NotFoundException
资源文件在编译阶段和打包阶段未被拷贝到指定的目录或者资源文件缺失。
3.5 非法参数问题
java.lang.IllegalArgumentException
API调用时传递了不合法或不正确的参数,包括参数类型错误,图形参数超出坐标范围等。
3.6 数据传输超限问题
android.os.TransactionTooLargeException
通常发生的问题包括在服务和应用之间交换大量的数据包括缓存等,在intent里传递大量数据,从服务中接收bitmap文件等
3.7 资源加载引起的超时问题
java.util.concurrent.TimeoutException
典型的Crash问题调用AssetManager处理资源时未考虑超时问题,也未考虑对超时异常情况进行拦截处理。
3.8 数据库问题
数据库操作暴露出的问题体现在在数据库的流程处理不合理和不正确,包括事务处理时没考虑事务的逻辑处理。
3.9 第三方Jar包,动态库和框架问题
引入很多第三方的库和框架,动态库在不同层面会体现出各种各样的问题。
3.10新特性引入的问题
APP引入新的特性时,会引入新的Crash问题,比如React-native和JavaScriptCore的库的改动。需要对RN的原理和框架以及JS引擎非常熟悉,加强Code Review并且充分的测试后才可减少产品上线后的Crash问题。
4 Crash问题的处理策略和方案
4.1 区分不同的类型问题采用不同的处理方案
对于空指针问题,越界问题,类查找问题,资源查找问题,非法参数问题,数据传输超限问题,资源加载引起的超时问题,数据库问题,Bundle加载问题等通过代码扫描工具以及静态安全检测工具并结合Code Review在编译阶段和代码提交阶段就尽可能避免,同时通过增加测试用例包括边界点测试进一步避免Crash问题。
对于第三方Jar包,动态库和框架问题,需要追踪第三方Jar包,动态库以及框架问题并和第三方框架比如提供商进行沟通和联系,分析问题并推动问题的解决。
新特性引入的问题,则需要加强对原理和框架的理解,并尽可能拦截住所有触发Crash的问题包括Java层面和C/C++层面,同时加强代码评审。
4.2 分阶段逐步解决问题逐步降低Crash率
先通过加强Code Review, 加强代码扫描,代码检测和安全检查,并通过增加异常的处理来减少可能的Crash率;
对Java层面包括Jar包触发Crash的重点问题重点关注;并根据Crash问题分析总结反馈补充测试用例和测试场景。
在Java层面的Crash问题降低到合理和允许的范围后,再考虑C/C++层面的Crash问题。
5 Crash问题的方案总结