美文网首页Android高级进阶Android进阶之路Android开发
都知道避免ANR,但该如何分析,定位,解决?

都知道避免ANR,但该如何分析,定位,解决?

作者: 小小小小怪兽_666 | 来源:发表于2020-04-28 16:23 被阅读0次

    一、什么是Anr:

    application not responding 程序无响应。程序在规定的时间内没有响应。

    超时时间的计数一般是从按键分发给app开始。超时的原因一般有两种:

    1.当前的事件没有机会得到处理(即UI线程正在处理前一个事件,没有及时的完成或者looper被某种原因阻塞住了);

    2.当前的事件正在处理,但没有及时完成。

    二、Anr的主要原因

    ANR一般有三种类型:

    1:KeyDispatchTimeout(5 seconds) --主要类型

    按键或触摸事件在特定时间内无法得到响应

    2:BroadcastTimeout(10 seconds)

    BroadcastReceiver在的onRecieve运行在主线程中,短时间内无法处理完成导致

    3:ServiceTimeout(20 seconds) --小概率类型

    Service的各个声明周期在特定时间内无法处理完成

    Anr场景分析

    1.使用命令导出anr日志

    adb pull /data/anr/traces.txt  ~/Desktop/
    

    2.分析关键信息

    以每行的重点内容没准,每行自带时间戳

    
    Process:anr发生的时间和进程,和生成traces文件的时间
    CPUusage ... ago :cpu在anr发生前的使用情况
    CPUusage ...later: cpu在anr后的使用情况
    ABI:         手机的cpu架构
    HEAP:     堆的内存信息
    ANR in:包名,和类名
    Reason:原因
    TOTAL:总的CPU使用率
    prio:线程的优先级
    tid:线程锁id  主线程的id为1  主要看这个线程的
    Sleeping:线程的状态
    sCount:线程被挂起的次数
    dsCount:线程是否被调试
    
    04-01 13:12:11.572** I/InputDispatcher( 220): Application is not responding**:Window{2b263310com.[Android](http://lib.csdn.net/base/android).email/com.android.email.activity.SplitScreenActivitypaused=false}.  5009.8ms since event, 5009.5ms since waitstarted
    04-0113:12:11.572 I/WindowManager( 220): Input event dispatching timedout sending tocom.android.email/com.android.email.activity.SplitScreenActivity
    04-01 **13:12:14.123 I/Process(  220): Sending signal. PID: 21404 SIG: 3---****发生**ANR**的时间和生成**trace.txt**的时间**
    04-01 13:12:14.123 I/dalvikvm(21404):threadid=4: reacting to signal 3 
    ……
    
    04-0113:12:15.872 E/ActivityManager(  220): ANR in com.android.email(com.android.email/.activity.SplitScreenActivity)
    04-0113:12:15.872 E/ActivityManager(  220): Reason:keyDispatchingTimedOut
    04-0113:12:15.872 E/ActivityManager(  220): Load: 8.68 / 8.37 / 8.53
    04-0113:12:15.872 E/ActivityManager(  220): **CPUusage from 4361ms to 699ms ago** ----CPU在ANR发生前的使用情况
    
    04-0113:12:15.872 E/ActivityManager(  220):   5.5%21404/com.android.email: 1.3% user + 4.1% kernel / faults: 10 minor
    04-0113:12:15.872 E/ActivityManager(  220):   4.3%220/system_server: 2.7% user + 1.5% kernel / faults: 11 minor 2 major
    04-0113:12:15.872 E/ActivityManager(  220):   0.9%52/spi_qsd.0: 0% user + 0.9% kernel
    04-0113:12:15.872 E/ActivityManager(  220):   0.5%65/irq/170-cyttsp-: 0% user + 0.5% kernel
    04-0113:12:15.872 E/ActivityManager(  220):   0.5%296/com.android.systemui: 0.5% user + 0% kernel
    04-0113:12:15.872 E/ActivityManager(  220): **100%TOTAL: 4.8% user + 7.6% kernel + 87% iowait**
    04-0113:12:15.872 E/ActivityManager(  220): **CPUusage from 3697ms to 4223ms later**:-- ANR后CPU的使用量
    04-0113:12:15.872 E/ActivityManager(  220):   25%21404/com.android.email: 25% user + 0% kernel / faults: 191 minor
    04-0113:12:15.872 E/ActivityManager(  220):    16% 21603/__eas(par.hakan: 16% user + 0% kernel
    04-0113:12:15.872 E/ActivityManager(  220):    7.2% 21406/GC: 7.2% user + 0% kernel
    04-0113:12:15.872 E/ActivityManager(  220):    1.8% 21409/Compiler: 1.8% user + 0% kernel
    04-0113:12:15.872 E/ActivityManager(  220):   5.5%220/system_server: 0% user + 5.5% kernel / faults: 1 minor
    04-0113:12:15.872 E/ActivityManager(  220):    5.5% 263/InputDispatcher: 0% user + 5.5% kernel
    04-0113:12:15.872 E/ActivityManager(  220): **32%TOTAL: 28% user + 3.7% kernel**
    

    典型的分析情况

    1.如果TOTAL的和接近100,有可能是因为当前使用的app占用的cpu太高,导致系统将你的杀死。

    2.如果TOTAL很小,则说明线程被阻塞了,主线程在等待下条消息的进入,任务在等待时anr。

    3.如果ioWait很高,则说明是io操作导致的

    分析

    因为主线程被阻塞导致的关键信息。

    at android.os.MessageQueue.nativePollOnce(Native Method) at android.os.MessageQueue.next(MessageQueue.java:119) at android.os.Looper.loop(Looper.java:110)

    
    DALVIK THREADS:(mutexes: tll=0tsl=0 tscl=0 ghl=0 hwl=0 
    hwll=0)"main" prio=5 tid=1NATIVE  | group="main" sCount=1 
    dsCount=0obj=0x2aad2248 self=0xcf70  | sysTid=21404 nice=0 
    sched=0/0cgrp=[fopen-error:2] 
    handle=1876218976  
    
    at android.os.MessageQueue.nativePollOnce(Native Method)  
    at android.os.MessageQueue.next(MessageQueue.java:119)  
    at android.os.Looper.loop(Looper.java:110**) 
    at android.app.ActivityThread.main(ActivityThread.java:3688)
     at java.lang.reflect.Method.invokeNative(Native Method)  
    at java.lang.reflect.Method.invoke(Method.java:507)  
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:624) 
    at dalvik.system.NativeStart.main(Native Method)
    

    io读写导致的anr

    关键点:ioWait很高,ContentResolver in AsyncTask onPostExecute

    1.首先看到total中ioWait很高,说明是io操作导致的。

    2.具体原因

    可以看到关键词sqlite,ContentResolver

    在主线程进行了网络访问

    关键词OSNetworkSystem.receiveStream,net

    内存不足导致

    可以看到TOTAL的使用率有98,所以内存不足。

    关键词:VMWAITVMRuntime.trackExternalAllocation

    广播阻塞导致anr

    android.intent.action.SCREEN_OFF广播为order,即如果其中注册了此广播的任何应用在处理此广播时未返回,则会导致后续broadcast的失败,出现ANR,导致系统无法唤醒。而导致广播未被及时处理的原因,除了可能是由于对应的Receiver处理函数中一些操作长时间未完成外,也可能是由于整个应用进程被block了,从而没有机会去调用Receiver函数。

    1.针对onRecieve中的耗时操作,可以将业务单独加入到一个线程中执行:

    快速定位anr

    1.如果是ANR问题 , 则搜索“ANR”关键词 。快速定位到关键事件信息 。

    2.如果是ForceClosed(程序强制关闭) 和其它异常退出信息,则搜索"Fatal" 关键词, 快速定位到关键事件信息 。

    ANR的避免和检测

    使用StrictModel

    它是android sdk提供的一个用来检测代码中是否存在违规操作的工具类

    1.线程检测策略

    ThreadPolicy

    1.detectCustomSlowCalls:检测耗时操作
    2.detectDiskWrites:检测磁盘写入
    3.detectDiskRead:检测磁盘读取
    4.detectNetWork:检测网络
    5.detectAll:启用所有策略

    VmPolicy

    虚拟机检测策略

    1.detectActivityLeaks:是否存在activity泄露
    2.detectLeakedClosableObjects:是否存在没有关闭的closable对象
    3.detectLeakedSqlLiteObjects:是否存在sqlite对象泄露
    4.detectClassInstanceLimit:是否存在实力个数超限制
    5.detectALL:启用所有策略

    使用方式

    在application的oncreate方法前
    StrictMode.setThreadPolicy(new StrictModel.ThreadPolicy.Builder().detectAll().penaltyLog().build());
    //penlatyLog表示是否打印日志。
    

    文末

    最后对于程序员来说,要学习的知识内容、技术有太多太多,要想不被环境淘汰就只有不断提升自己,从来都是我们去适应环境,而不是环境来适应我们!

    这里附上上述的技术体系图相关的几十套腾讯、头条、阿里、美团等公司19年的面试题,把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,这里以图片的形式给大家展示一部分。

    相信它会给大家带来很多收获:

    上述【高清技术脑图】以及【配套的架构技术PDF】可以 关注我 【主页简介】 或者【简信】免费获取

    Android学习PDF+架构视频+面试文档+源码笔记

    当程序员容易,当一个优秀的程序员是需要不断学习的,从初级程序员到高级程序员,从初级架构师到资深架构师,或者走向管理,从技术经理到技术总监,每个阶段都需要掌握不同的能力。早早确定自己的职业方向,才能在工作和能力提升中甩开同龄人。

    相关文章

      网友评论

        本文标题:都知道避免ANR,但该如何分析,定位,解决?

        本文链接:https://www.haomeiwen.com/subject/cgfbwhtx.html