ANR产生原因以及分析工具

ANR产生原因:

  • 只有当应用程序的UI线程响应超时才会引起ANR,超时原因:
    • 当前事件没有机会得到处理
    • 当前的事件正在处理,但是由于耗时太长没能及时完成
  • 引发ANR的原因;
    • View的按键事件或者触摸事件在5s内无法得到响应
    • BroadcastReceiver的onReceive()函数在10s内没有得到处理
    • Service各个生米周期函数在20s内没有得到处理

典型的ANR场景分析:

  • 应用程序UI线程存在耗时任务,例如在UI线程中进行网络请求(Android4.0之前,4.0之后会报错),数据库操作或者文件操作等,可能会导致UI线程无法及时处理用户的输入。
  • UI线程等待子线程释放某个锁,从而用户无法输入
  • 耗动画可能需要大量的计算工作,可能导致CPU负载过重

ANR的避免和检测:

StrictMode: 是AndroidSDk提供的一个用来检测代码中是否存在违规操作的工具类,它主要检测两大类问题:
  • 线程策略ThreadPolicy

    • detectCustomSlowCalls:检测自定义耗时操作
    • detectDiskReads:检测是否存在磁盘读取操作
    • detectDiskWrites:检测是否存在磁盘写入操作
    • detectNetwork:检测是否存在网络操作
  • 虚拟机策略VmPolicy

    • detectActivityLeaks:检测是否存在Activity泄漏
    • detectLeakedClosableObjects:检测是否存在未关闭的Closable对象泄漏
    • detectLeakedSqlLiteObjects:检测是否存在Sqlite的对象泄漏
    • setClassInstanceLimit:检测类实例个数是否超过限制
  • StrictMode的使用: 在应用初始化的地方Application或者MainActivity类的onCreate方法中执行:

if(BuildConfig.DEBUG){
    //开启线程策略
    StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().detectAll().penaltyLog().build());
    //开启虚拟机模式 
    StrictMode.setVmPolicy(new VmPolicy.Builder().detectAll().penaltyLog().build());
}
super.onCreate(savedInstanceState);
BlockCanary:是一个非侵入式的性能监控函数库,用法和LeakCanary类似,BlockCanary主要用来监控应用主线程的卡顿,基本原理就是利用主线程的消息队列处理机制,通过对比消息分发开始和结束的时间点来判断是否超过设定的时间,如果是,则判断主线程卡顿,下面是使用的方法
  • 首先在app下的build.gradle中的dependencies中添加如下代码:
dependencies {
    ...
    implementation 'com.github.markzhai:blockcanary-android:1.5.0'
     // 仅在debug包启用BlockCanary进行卡顿监控和提示的话,可以这么用
    debugCompile 'com.github.markzhai:blockcanary-android:1.5.0'
    releaseCompile 'com.github.markzhai:blockcanary-no-op:1.5.0'
}
  • 在Application中:
public class DemoApplication extends Application {
    @Override
    public void onCreate() {
        // 在主进程初始化调用哈
        BlockCanary.install(this, new AppBlockCanaryContext()).start();
    }
}

猜你喜欢

转载自blog.csdn.net/qq_39424143/article/details/94722714