Android App性能优化之稳定性问题分类
1. ANR
2. Crash
3. 应用退出
1. ANR
ANR(Application Not Responding 应用程序无响应)
1.1大致可分为三类情况:
- 输入事件响应超时(主要类型):主线程(“事件处理线程”、“UI线程”)在5秒内没有响应输入事件。
- 广播接收处理超时:BroadcastReceiver 没有在10秒内完成返回。
前台广播为10s,后台广播为60s,默认发送的为后台广播
发送广播时,携带Intent.FLAG_RECEIVER_FOREGROUND将广播设置为前台广播
- Service服务处理超时(小概率事件):Service在20秒(前台5s,后台service为200s,默认为后台服务)内没有执行完成应用发起的service请求。
前台服务:超时时间为5s,通过startForegroundService将指定服务指定为前台服务,会在notification中存在提示信息。
被前台进程binder的服务:service服务被前台进程binder,那么此服务的超时时间为20s。
被后台进程binder的服务:service服务被后台进程binder,那么此服务的超时时间为200s。
1.2 原因分析
- 程序自身主线程问题引起的ANR,通过ANR的tombstone backtrace定位。
主进程进行IO文件操作。
主进程进行大量频繁的数据库操作。
主进程进入死循环。
高耗时的操作,如图像变换。
大量的创建新对象。
存在耗时的计算。
主线程错误操作,如Thread.wait。
- iowait过高,此类异常是后台有进程在进行大量io磁盘操作。
- cpu占用率过高,查看backtrace中cpu信息,查看哪个进程占用cpu较高,具体分析较高的进程是否正常。
- 内存过低,手机在内存过低的情况下,系统会不断kill掉优先级低进程。
1.3 排查流程
- Log获取
抓取bugreport,输入命令:adb shell bugreport > bugreport.txt
直接导出/data/anr/traces.txt文件,输入命令:adb pull /data/anr/traces.txt trace.txt
- 搜索 “ANR in” 处的log关键点解读
2. Crash
2.1 Crash 出现的常见场景
- NullPointerException 空指针
- IndexOutOfBoundsException 下标越界异常
- ClassCastException 类型转换异常
- ActivityNotFoundException Activity 未找到异常
- IllegalStateException 非法状态异常
- SecurityException 安全异常
- ArrayIndexOutOfBoundsException 数组越界异常
- OOM OutOfMemoryError 内存溢出
减少对象的内存占用
内存对象的重复使用
避免对象的内存泄漏
内存使用策略优化
- 内存泄漏
LeakCanary 内存泄漏检测工具
https://github.com/square/leakcanary
常见场景
a、类的静态变量持有大数据对象
b、非静态内部类存在静态实例
c、资源对象未关闭
d、Bitmap 未释放
e、注册未取消
f、集合中对象没清理
g、Handler 内存泄漏,声明Handler为static类,这样子内部类就不在持有外部类的引用了
h、构造Adapter时,未使用缓存的convertView
如何避免
a、使用更加轻量的数据接口,比如使用ArrayList代替HashMap
b、避免使用枚举 Enum
c、减少Bitmap对象的内存占用
d、使用StringBuilder代替String+=
e、避免在onDraw方法里面执行对象的创建
- 依赖库问题
Android App 经常会依赖很多aar,每个aar可能有多个版本,如果互相依赖的aar有不兼容的办办,存在的问题在打包时不能发现的,只有在相关代码执行时才会出现,会造成比如NoClassDefFoundError、NoSuchMethodError、NoSuchFieldError等异常。
3. 应用退出
- 主动自杀
- Process.killProcess()、exit()
- 崩溃
- 系统重启
- 系统异常、断电等
- 被系统杀死
- 被LMK杀死、从系统的任务管理器中划掉等