zoukankan      html  css  js  c++  java
  • 一文带你了解ANR(测试人员)

    一、首先,了解一下什么是ANR

    ANR,是“Application Not Responding”的缩写,即“应用程序无响应”。系统会向用户显示一个对话框,用户可以选择“等待”而让程序继续运行,也可以选择“强制关闭”。

    在Android中,应用程序的响应是由Activity Manager和WindowManager系统服务监视的 。当它监测到A、B、C情况中的一个时,Android就会针对特定的应用程序显示ANR:

    • A.在5秒内没有响应输入的事件(例如,按键按下,屏幕触摸)--主要类型

    • B.BroadcastReceiver在10秒内没有执行完毕

    • C.Service在特定时间内(20秒内)无法处理完成--小概率类型

    造成ABC的原因有很多,比如在主线程中做了非常耗时的操作,如下载,io异常等。还需要注意的是产生这种ANR的前提是要有输入事件,如果用户没有触发任何输入事件,即便是主线程阻塞了,也不会产生ANR,因为InputDispatcher没有分发事件给应用程序,当然也不会检测处理超时和报告ANR了。

    各个应用进程和系统进程的函数堆栈信息都输出到了/data/anr/traces.txt的文件中

    二、ANR的一般分析思路

    1. 从手机的/data/traces/目录导出traces.txt文件;
    2. 从traces.txt文件获取ANR产生的时间点T1;
    3. 从traces.txt文件中获取main线程的运行状态、调用栈;
    4. 查看logcat日志,搜索“ANR in”,找出ANR产生的时间点T2,以及时间点T2前后几秒钟,在系统中运行的各进程CPU耗时占比;
    5. 在步骤4中找出目标进程的cpu耗时占比,确认是user占比高,还是kernel占比高,还是iowait占比高;
    6. 根据时间点T1、时间点T2,校准ANR产生的时间范围 [T1, T2] 或 [T2, T1];
    7. 查看logcat日志,将日志定位到步骤2)中获取的时间点 [T1, T2] 或 [T2, T1]附近;
    8. 查看logcat日志在时间点 [T1, T2] 或 [T2, T1]附近前后2分钟的日志,以还原ANR产生前后的场景;
    9. 根据以上步骤得出的信息,定位代码中可能的问题代码块;
    10. 解决问题,或提出阶段分析结论。

    三、测试人员碰到ANR问题,应该怎么做

    1. 首先,应该截图,保留“证据”;

    2. 描述清楚出现步骤,并尝试复现,确认是否必现或出现概率

    3. 导出traces文件

    获取traces文件命令:
    adb pull /data/anr
    
    1. 导出logcat日志信息。

    扩展一:traces文件信息解析

    开头显示进程号、ANR发生的时间点和进程名称

        ----- pid 9183 at 2012-09-28 22:20:42 ----
     Cmd line: com.example.anrdemo
    
    DALVIK THREADS: //以下是各个线程的函数堆栈信息
    //依次是:线程名、线程优先级、线程号、线程当前状态(TIMED_WAIT或SUSPENDED在anr时很常见)
    //线程名称后面标识有daemon,说明这是个守护线程
    
    "main" prio=5 tid=1 TIMED_WAIT
    //依次是:线程组名称、suspendCount个数、debugSuspendCount个数、线程的Java对象地址、线程的Native对象地址
    | group="main" sCount=1 dsCount=0 obj=0x4025b1b8 self=0xce68
    
    //sysTid是线程号,主线程的线程号和进程号相同
    | sysTid=9183 nice=0 sched=0/0 cgrp=default     
    handle=-1345002368| schedstat=( 140838632 210998525 213 )
    at java.lang.VMThread.sleep(Native Method)
    at java.lang.Thread.sleep(Thread.java:1213)
    .......
    
    
    //Binder线程是进程的线程池中用来处理binder请求的线程
    
    "Binder Thread #2" prio=5 tid=8 NATIVE
    | group="main" sCount=1 dsCount=0 obj=0x40750b90 self=0x1440b8
    | sysTid=9190 nice=0 sched=0/0 cgrp=default handle=1476256
    | schedstat=( 915528 18463135 4 )
    at dalvik.system.NativeStart.run(Native Method)
    
    
    
    //JDWP线程是支持虚拟机调试的线程,不需要关心
    
    "JDWP" daemon prio=5 tid=5 VMWAIT
    | group="system" sCount=1 dsCount=0 obj=0x4074b878 self=0x16c958
    | sysTid=9187 nice=0 sched=0/0 cgrp=default handle=1510224
    | schedstat=( 366211 2807617 7 )
    t dalvik.system.NativeStart.run(Native Method)
    //“Signal Catcher”负责接收和处理kernel发送的各种信号,例如SIGNAL_QUIT、SIGNAL_USR1等就是被该线程
    //接收到,这个文件的内容就是由该线程负责输出的,可以看到它的状态是RUNNABLE,不过此线程也不需要关心
    
    "Signal Catcher" daemon prio=5 tid=4 RUNNABLE
    | group="system" sCount=0 dsCount=0 obj=0x4074b7b8 self=0x150008
    | sysTid=9186 nice=0 sched=0/0 cgrp=default handle=1501664
    | schedstat=( 1708985 6286621 9 )
    

    扩展二:如何避免ANR

    1. 绝对不要在主线程上进行复杂耗时的操作,比如说发送接收网络数据、进行大量计算、操作数据库、读写文件等,统统采用异步操作

    2. broadCastReceiver 要进行复杂操作的的时候,可以在onReceive()方法中启动一个IntentService或者JobIntentService去做。

    3. Service中的耗时操作最好也是采用异步任务

    4. 在设计及代码编写阶段避免出现出现同步/死锁、死循环等不恰当情况

  • 相关阅读:
    JQ用法
    js查漏补缺【未完】
    VSCode里面HTML添加CSS时没有提示
    CSS查漏补缺【未完】
    HTML查漏补缺 【未完】
    Android Bitmap 全面解析(二)加载多张图片的缓存处理
    android Paint 详解
    Android Bitmap 全面解析(一)加载大尺寸图片
    图片处理框架
    [项目总结]论Android Adapter notifyDataSetChanged与notifyDataSetInvalidated无效原因
  • 原文地址:https://www.cnblogs.com/51benpao/p/13027195.html
Copyright © 2011-2022 走看看