Android ANR 原因分析与检测
2017-09-27 00:02
99 查看
Android ANR 原因分析与检测
ANR,即应用程序不响应(Application Not Responding)。在主线程中进行某些耗时操作,超过一定时间,系统就会弹出ANR对话框。此时可以选择等待,让程序跑完,也可以选择关闭应用程序。一、 ANR 原因分析
只有当应用程序的UI线程响应超时才会引起ANR,超时产生的原因一般有两种:当前事件没有机会得到处理,例如UI线程正在响应另一个事件,当前事件由于某种原因被阻塞了
当前事件正在处理,但是由于耗时太长未能及时完成
本质上,产生ANR的原因有三种:KeyDispatchTimeout、BroadcastTimeout、ServiceTimeout
1.1 KeyDispatchTimeout
View的按键事件或者触摸事件这特定事件(5秒)内无法得到响应1.2 BroadcastTimeout
BroadcastReceiver 的 onReceive()方法在特定时间(10秒)内无法完成处理(onReceive是运行在主线程的)1.3 ServiceTimeout
Service 的各个生命周期函数在特定时间(20秒)内无法完成处理二、ANR 避免
一个原则:主线程尽量只做UI相关的事,耗时操作(如文件读取,数据库读写等),计算量大的任务,在线程中执行,完成之后通过Handler来更新UI。2.1 主线程
运行在主线程的有:1. Activity的各个生命周期 onCreate(),onResume(),onDestory,点击/触摸事件等
2. Service的各个生命周期
3. BroadcastReceiver的onReceive()方法。
4. AsyncTask: onPreExecute(), onProgressUpdate(), onPostExecute(), onCancel
5. Mainthread handler: handleMessage(), post*(runnable r)
6. View的post()方法
在以上的这些方法内,尽量不要执行耗时的操作,如读写数据库,文件等。可以放在线程中运行,完成后再通知更新主线程。
2.2 异步处理技术
Android SDK提供了很多异步处理技术1. Thread + Handler
2. HandlerThread
3. AsyncTask
4. IntentService
5. AsyncQueryHandler(用于ContentProvider上执行异步的CRUD)
6. Loader(Android 3.0引入的一个异步数据加载框架)
除了Android SDK提供的异步技术外,比较火的RxAnroid使用起来更加方便简洁,流程更加清晰,代码更加易于理解,功能更加强大(反正说是牛逼轰轰,确实也是很好用)。
三、ANR 定位分析
发生ANR后,可以结合Logcat日志和位于收集内部存储的/data/anr/trace.txt文件进行分析和定位。Cash和ANR的异常信息统计,一般可以接入第三的统计SDK,如友盟或者Bugly,不需要自己实现后台,便可以实时获得APP的异常统计信息,可以专注于问题的分析和定位。但是,为了更好地理解解决的思路,还是有必要了解信息是的来源和如何收集。3.1 Logcat 日志信息
发生ANR后,可以查看Logcat日志,日志中有ANR的类型,时间等信息,参考浅谈ANR及log分析ANR3.2 traces.txt 日志信息
有时候根据Logcat日志无法定位到问题的具体位置,这时候就需要traces.txt中的日志信息。traces.txt位于设备的 /data/anr/traces.txt文件中(因为权限限制,在应用中无法读取,如果可以读取就可以上报给后台,实现自己的ANR日志收集SDK),链接上PC后可以通过adb命令导出:
adb pull /data/anr/traces.txt C:\Users\YourName\Desktop\traces.txt
如何分析traces.txt日志?参考:
Android App优化之ANR详解
android anr traces日志分析方法
3.3 第三方统计SDK
Logcat 日志和trace.txt日志都需要有设备才能获取到,而实际中几乎不可能拿到用户的设备来查看日志,所以,有必要有一个后台来收集错误信息。第一种方法是自己实现Crash和ANR信息收集;第二种方法是利用现有的第三方平台,如Bugly,友盟。使用第三方平台的好处是节约成本,专注于ANR的定位和问题的解决即可。四、ANR 检测
可以借助一些工具,在调试阶段进行违规代码的检测4.1 StrictMode
严格模式 StrictMode 是 Android SDK 提供的一个用来检测代码中是否存在违规操作的工具类,StrictMode主要检测两大类问题。线程策略ThreadPolicy
detectCustomSlowCalls 检测自定义耗时操作
detectDiskReads 检测是否存在磁盘读取操作
detectDiskWrites 检测是否存在磁盘写入操作
detectNetwork 检测是否存在网络操作
虚拟机策略VmPolicy
detectActivityLeaks 检测是否存在Activity泄漏
detectLeakedClosableObjects 检测是否存在未关闭的Closable对象泄漏
detectLeakedSqlLiteObject 检测是否存在Sqlite对象泄漏
setClassInstanceLimit 检测类实例个数是否超出限制
严格模式的使用并不复杂,在自定义的Application类或者MainActivity的onCreate()方法中加入以下代码即可:
@Override public void onCreate() { super.onCreate(); if (BuildConfig.DEBUG) { // 只在debug使用,release不使用严格模式 StrictMode.enableDefaults(); } }
enableDefaults()的实现如下:
/** * Enable the recommended StrictMode defaults, with violations just being logged. * * <p>This catches disk and network access on the main thread, as * well as leaked SQLite cursors and unclosed resources. This is * simply a wrapper around {@link #setVmPolicy} and {@link * #setThreadPolicy}. */ public static void enableDefaults() { StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder() .detectAll() .penaltyLog() .build()); StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder() .detectAll() .penaltyLog() .build()); }
启用了严格模式,在Logcat中过滤:tag = StrictMode即可看到输出的日志信息。然后根据输出的日志信息,检测是否存在问题,然后及时改正。
4.2 BlockCanary
BlockCanary 是一个非侵入式的性能监控函数库,它的用法和LeakCanary类似,只不过后者监控应用的内存泄漏,而BlockCanary主要用来监控应用的主线程卡顿,它的基本原理是利用主线程的消息队列处理机制,通过对比消息分发开始和结束的时间点来判断是否超过设定的时间,如果是则判断线程卡顿,它的集成很简单,在build.gradle中添加依赖: compile ‘com.github.moduth:blockcanary-android:1.2.1’,然后在Application中进行配置和初始化即可。@Override public void onCreate() { super.onCreate(); BlockCanary.install(this, new AppBlockCanaryContext()).start(); }
更多参考:blockcanary,BlockCanary解析
五、扩展
一、实现ANR信息收集SDK
前面介绍中的 Logcat 日志和 traces.txt 文件日志可以作为分析ANR的主要信息,而Logcat日志需要连接到PC利用IDE来查看,traces.txt文件/data/anr/traces.txt是没有读取权限的。所以,如何收集这些信息,上报到后台?(PS: bugly等第三方平台是如何实现的呢?)六、参考
Android App优化之ANR详解Android高级进阶
浅谈ANR及log分析ANR
blockcanary
BlockCanary解析
相关文章推荐
- Android中ANR产生的原因以及定位分析和检测
- Android ANR问题原因分析
- Android 耗时代码(ANR)的查找检测和分析解决 TraceView的使用手册
- Android ANR产生的原因及定位分析
- Android ANR产生的原因以及其定位分析
- Android App开发之ANR异常的原因分析及处理总结
- android crash 四 ANR原因分析及解决方法
- 在Android的TableLayout布局中,column和span属性“失效”原因分析与解决
- Android系统ANR以及Force Close出现的原因以及解决办法
- Android 中内存泄漏的原因分析及解决方案
- 【Arcgis for android】程序运行出错原因分析及解决(超详细)
- android ANR产生原因(三总常见类型)和解决办法
- android ANR源码分析 --- 之二
- ANR产生的原因及其定位分析
- hi3716c-android4.0.3SDK在开机动画阶段停留很长时间并黑屏不进入launcher原因分析
- android ListView 在初始化时多次调用getView()原因分析
- opencv人脸检测代码应用与分析(PC端和Android端)
- 在Android library中不能使用switch-case语句访问资源ID的原因分析及解决方案
- Android版本更新不成功原因分析
- android ANR产生原因和解决办法