美文网首页
五、ANR产生的原因及其定位分析

五、ANR产生的原因及其定位分析

作者: 锦文豪武 | 来源:发表于2018-09-21 18:01 被阅读0次

    ANR 全称Application Not Responding(应用程序无响应),一般页面卡顿时间超过(一般是5秒)一定时间就会出现ANR对话款。Logcat一般会发现ANR以及traces.txt等字样。出现ANR主要原因是因为我们在主线程中做了太多耗时操作。

    A、ANR产生的原因

    只有当应用程序的UI线程相应超时才会引起ANR,超时产生原因一般有两种
    (1)当前的事件没有机会得到处理,例如UI线程正在响应另外一个事件,当前事件由于某种原因被阻塞了。
    (2)当前事件正在处理,但是由于耗时太长没能及时完成

    根据ANR产生的原因不同,超时事件也不尽相同,从本质上讲,产生ANR的原因有三种,大致可以对应到Android 中四大组件中的三个(activity/view,BroadcastReceiver和service)。

    (1)KeyDispatchTimeOut类型

    最常见的一种类型,原因是View的按键事件或触摸事件在特定的事件(5秒)内无法得到响应

    (2)BroadcastTimeOut类型

    原因是BroadcastReciver的onReceive()函数运行在了主线程中,在特定的事件(10秒)内无法完成处理

    (3)ServiceTimeOut类型

    比较少出现的一种类型,原因是Service的各个生命周期函数在特定时间(20秒)内无法完成处理

    B、典型的ANR问题场景

    (1)场景一:

    应用程序UI线程存在耗时操作,例如在UI线程中进行网络请求,数据库操作或者文件操作等,可能会导致UI线程无法及时处理用户输入等。当然在Android4.0之后,如果在UI线程中进行网络操作,将会抛出NetworkOnMainTreadException异常。

    (2)场景二:

    应用程序的UI线程等待子线程释放某个锁,从而无法处理用户的输入。

    (3)场景三:

    耗时的动画需要大象的计算工作,可能会导致CPU负载过重

    C、ANR的定位和分析

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

    (1)Logcat日志信息

    查看日志

    (2)traces.txt日志信息

    有助于问题已定位的信息主要内容

    a、发生ANR的进程名称、ID,以及时间。

    b、其他

    QQ图片20180921175250.png

    c、主工程基本信息

    QQ图片20180921175347.png

    d、主线程的详细信息

    QQ图片20180921175423.png

    e、线程的调度信息

    QQ图片20180921175502.png

    f、线程的上下文信息

    QQ图片20180921175543.png

    g、线程的堆栈信息

    QQ图片20180921175624.png

    D、ANR的避免和检测

    (1)不要在主线程中做耗时操作

    为了避免开发中可能发生的ANR的问题,除了切记不要再主线程中做耗时操作,我们也可以借助一些工具来进行检测,从而更有效的避免ANR的引入

    (2)StrictMode(代码检测)

    严格模式StrictMode 是Android SDK提供的一个用来检测代码是否存在违规操作的工具类,StrictMode 主要检测两大类为题

    a、线程策略ThreadPolicy

    检测可能存在的主线程耗时操作,解决这些检测到的问题能够减少应用发生的ANR的概率。需要注意的是我们只能在DEbug版本中使用它,发布到市场版本必须关掉。


    QQ图片20180921175750.png

    b、虚拟机策略VmPolicy QQ图片20180921175827.png

    c、StrictMode使用

    使用很简单,我们只需要在应用初始化的地方例如Application或者MainActivity类中onCreate方法中执行如下代码

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        if (BuildConfig.DEBUG) {
            /**开启线程模式*/
            StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().detectAll().penaltyLog().build());
            /**开启虚拟机模式*/
            StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().detectAll().penaltyLog().build());
        }
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_anr);
    }
    

    调用detectAll表示检测所有的检测策略,我们也可以根据应用需求只开启一些策略

    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    if (BuildConfig.DEBUG) {
        /**开启线程模式,某些策略*/
        StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
                .detectDiskReads()
                .detectDiskWrites()
                .detectCustomSlowCalls()
                .penaltyLog()
                .build());
    
        /**开启虚拟机模式,某些策略*/
        StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
                .detectActivityLeaks()
                .detectLeakedRegistrationObjects()
                .penaltyLog()
                .build());
    }
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_anr);
    }
    

    BlockCanary(非侵入式性能监控函数库)

    BlockCanary是一个非侵入时的性能监控函数库,他的用法和LeakCanary类似,只不过LeakCanary检测内存泄漏,而BlockCanary主要用来监控应用主线程的卡顿,它的基本原理利用主线程的消息队列处理机制,通过对比消息分发开始和结束的事件点来判断是否超过设定的时间,如果是,则判断为主线程卡顿。
    集成顺序:

    a、build.gradle添加依赖

    //主线程卡顿监控依赖
    implementation 'com.github.moduth:blockcanary-android:1.5.0'
    //如果仅在debug 包启用BlockCanary 进行卡顿监控和提示的话,这样写
    //debugCompile 'com.github.moduth:blockcanary-android:1.5.0'
    //releaseCompile 'com.github.moduth:blockcanary-no-op:1.5.0'
    

    b、在Application中调用

    @Override
    public void onCreate() {
    super.onCreate();
    /**初始化调用*/
    BlockCanary.install(this,new AppBlockCanaryContext()).start();
    }
    
    public class AppBlockCanaryContext extends BlockCanaryContext{
    /**
     * 实现各种上下文,包括应用标识符、用户uid、网络类型、卡曼判断阈值、Log保存位置等
     */
    }
    

    相关文章

      网友评论

          本文标题:五、ANR产生的原因及其定位分析

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