性能优化3 – ANR 与 Crash监控

ANR

概念

ANR即应用程序无响应。
UI线程被阻塞太长时间,就会出现ANR,然后弹框,结束进程、继续等待。

类型

KeyDispatchTimeout(常见)
input事件在5S内没有处理完成发生了ANR
logcat日志关键字:Input event dispatching timed out

BroadcastTimeout
前台Broadcast:onReceiver在10S内没有处理完成发生ANR。
后台Broadcast:onReceiver在60s内没有处理完成发生ANR。
logcat日志关键字:Timeout of broadcast BroadcastRecord

ServiceTimeout
前台Service:onCreate,onStart,onBind等生命周期在20s内没有处理完成发生ANR。
后台Service:onCreate,onStart,onBind等生命周期在200s内没有处理完成发生ANR
logcat日志关键字:Timeout executing service

ContentProviderTimeout
ContentProvider 在10S内没有处理完成发生ANR。
logcat日志关键字:timeout publishing content providers

总结:
image.png

产生原因

1:主线程进行耗时操作:如数据库读写、IO读写、网络请求等
2:多线程操作的死锁,主线程被block;
3:主线程被Binder 对端block;
4:System Server中WatchDog出现ANR;
5:service binder的连接达到上线无法和和System Server通信
6:系统资源已耗尽(管道、CPU、IO)

解决

1.在主线程里尽可能的少做事,将耗时操作都放到子线程中执行。特别是在Acitivty生命周期(onCreate/onResume())里减少创建操作,潜在的耗时操作。(网络请求、数据库操作、计算位图尺寸等)放到子线程,然后通过Handler提交到主线程,而不是wait()sleep()等在那

2.别再广播里做耗时操作。放到Service里或者子线程。

3.如果真有耗时操作的话,可以做一个进度条,避免用户以为死机了。

捕获与监控

1.在开发阶段出现ANR

在开发阶段出现还是比较好解决的,只需要看报错的日志就可以了。然后定位到具体的代码行数。没找到的话,可以找/data/anr/traces.tet文件,这个文件记录了ANR日志。

/data/anr/traces.tet文件:
主要看1.CPU、用户态、内核态、IO的利用率。哪个利用率高了,就是那个出问题了。
2.堆栈的利用率。
3.看“main” 的报错情况,自己写的错误一般都在这。

G.png

2.线上部分手机出现ANR
1.集成第三方:bugly、蒲公英、极光等监控,在那看ANR发生的手机型号、错误日志等。然后去找同款手机去测试一下(没有可以去云测)
2.自己监控: FileObserver、watchdog
FileObserver
FileObserver是一个抽象类,定义一个子类去继承他,实现onEvent方法。然后监控/data/anr/这个目录下有没有新文件产生,有的话就说明有ANR,然后传到服务器上。
watchdog看门狗,android系统就用的这个

Crash监控

Crash也就是闪退。闪退分为Java层的闪退和native层的闪退。

Java层的Crash

闪退就是发生了没有捕获的异常,处理不了了,然后就弹一个框“程序崩溃”,然后app就退出了。

1.获取UncaughtExceptionHandler Thread.getDefaultUncaughtExceptionHandler();
2.实现UncaughtExceptionHandler接口
3.在这个方法里就有了uncaughtException

在这里可以将报错信息Throwable存到本地,然后发送给服务器(时间、手机型号、app版本等自己写)
然后最重要的还得调用系统的uncaughtException方法,不然程序虽然不会崩溃,但是会卡死、无限重启。

image.png

系统怎么处理的
RuntimeInit.java -> KillApplicationHandler
也是实现UncaughtExceptionHandler接口
image.png

1.在try里通过AMS弹窗
2.在finally里杀死app进程
image.png

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享