异常——ANR

2018-09-09  本文已影响0人  Samuel_Tom

什么是ANR异常

ANR即Application Not Responding程序无响应,主要有以下三种情况会报ANR异常:

1、Activity的响应时间超过5s;

2、BroadcastReceiver执行时间超过10s;

3、Service执行时间超过20s;

造成ANR的原因

1、在主线程中执行了耗时操作,比如网络读取图片数据并进行图片转换;

2、在主线程中进行IO读写、磁盘读写、数据库读写等操作;

3、在主线程中大量创建新对象;

Android中执行在主线程的操作

1、Activity的所有生命周期回调方法;

2、Service默认是执行在主线程的;

3、BroadcastReceiver的onReceiver()回调方法;

4、没有使用子线程的looper的Handler的handlerMessage()方法,post(Runnable r)方法;

5、AsyncTask除了doInBackground()方法之外其它的方法都是执行在主线程中;

如何避免ARN

1、在UI线程中不要进行耗时操作;比如在Activity的onCreate()或者onResume()生命周期中不要做耗时操作;

2、创建子线程来执行耗时操作;

3、尽量使用Handler来处理主线程和子线程之间的交互;

4、可以使用AsyncTask来执行异步任务并及时更新UI;

如何排查ANR

1、查看报错的Log日志文件;具体可查看ANR的类型,CPU的使用情况等信息,并不能进行准确定位;

2、分析traces.txt文件;如果发生ANR异常,系统会在/data/anr/目录下生成traces.txt文件,可以通过分析traces.txt文件来查看产生ANR的原因,但前提是手机需要Root获取相应的权限;

3、使用BlockCanary第三方监控组件,BlockCanary可以对主线程进行完全透明的监控,而且如果遇到UI卡顿时能精确输出信息定位到问题所在,不需要像Logcat一样,慢慢去找。

BlockCanary的工作原理:

主要利用了主线程中的消息处理机制,在主线程中ActivityThread会默认创建一个Looper,而Looper会调用loop()方法不断从消息队列MessageQueue取出消息,然后通过dispatchMessage()方法进行消息的处理,通过ActivityThread的源码可以发现在dispatchMessage()方法的前后都有log输出事件,而dispatchMessage()是一次消息的处理过程,我们就可以计算从消息处理开始到消息处理结束的时间,如果这个时间超过了16ms的话,那么就可以认定是发生了UI卡顿现象,进而输出异常日志信息。

BlockCanary输出的信息:

(1)基本信息:安装包标示、机型、api等级、uid、CPU内核数、进程名、内存、版本号等;

(2)耗时信息:实际耗时、主线程时钟耗时、卡顿开始时间和结束时间;

(3)CPU信息:时间段内CPU是否忙,时间段内的系统CPU/应用CPU占比,I/O占CPU使用率;

(4)堆栈信息:发生卡慢前的最近堆栈,可以用来帮助定位卡慢发生的地方和重现路径;

推荐阅读:

BlockCanary — 轻松找出Android App界面卡顿元凶

上一篇下一篇

猜你喜欢

热点阅读