Android之ANR(Application Not Resp

2018-02-13  本文已影响0人  Amy_LuLu__

注意:本篇文章是本人阅读相关文章所写下的总结,方便以后查阅,所有内容非原创,侵权删。

本篇文章内容来自于:
Android高级进阶 顾浩鑫
Android ANR产生的原因以及其定位分析

目录

  1. 什么是ANR
  2. ANR产生的原因
  3. 典型的ANR问题场景
  4. ANR发生了 如何定位和分析
  5. ANR的避免和检测
    --5.1 StrictMode
    --5.2 BlockCanary

1. 什么是ANR

ANR:Application Not Responding。
ANR的直观体验是用户在操作APP的过程中,感觉界面卡顿,当卡顿时间超过一定时间(一般5s)就会出现ANR对话框。

2. ANR产生的原因

主要是因为我们在主线程中做了太多的耗时操作。
超时产生原因一般有2种:

  1. 当前的事件没有机会得到处理。
    例如UI线程正在响应另外一个事件,当前事件由于某种原因被阻塞了。
  2. 当前事件正在处理,但是由于耗时太长没能及时完成。

根据ANR产生的原因不同,超时时间也不尽相同。
从本质上讲产生ANR的原因有3种:
大致可以对应到Android四大组件中的三个(Activity/View、BroadcastReceiver、Service)

  1. KeyDispatchTimeout
    最常见的一种类型,原因是view的按键事件或者触摸事件在特定的时间(5s)内无法得到响应。
  2. BroadCastTimeout
    原因是BroadCastReceiver的onReceive()函数运行在主线程,在特定的时间(10s)内无法完成处理。
  3. ServiceTimeout
    比较少出现的一种类型,原因是Service的各个生命周期函数在特定时间(20s)内无法完成处理。

3. 典型的ANR问题场景

4. ANR发生了 如何定位和分析

当发生ANR时,可通过结合logcat日志和生成的位于手机内部存储的/data/anr/traces.txt文件进行分析和定位。

5. ANR的避免和检测

5.1 StrictMode

严格模式StrictMode是Android SDK提供的一个用来检测代码中是否存在违规操作的工具类。
主要用于检测两大类问题:(1)可能存在的主线程耗时操作 (2)是否发生泄漏

只能在Debug版本使用它,发不到市场上的版本要关掉。
使用
只需要在应用初始化的地方例如Application或者MainActivity的onCreate方法中执行代码:

        if (BuildConfig.DEBUG) {
            //===开启线程模式===
            //开启全部
            StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().detectAll().penaltyLog().build());
            //开启部分
            StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().detectDiskReads().detectDiskWrites().detectNetwork().penaltyLog().build());
            //===开启虚拟机模式===
            //开启全部
            StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().detectAll().penaltyLog().build());
            //开启部分
            StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().detectActivityLeaks().detectLeakedSqlLiteObjects().detectLeakedClosableObjects().penaltyLog().build());
        }

5.2 BlockCanary

github地址

上一篇 下一篇

猜你喜欢

热点阅读