ANR治理

547 阅读2分钟

ANR简介

ANR是“应用无响应”(Application not responding)的简称,ANR发生时用户输入行为无响应、前台会展示ANR弹窗。

image.png

知识储备

线程与进程

线程是基本的cpu执行的单元,程序执行流的最小单元,不拥有系统资源,与其他线程共享资源。 进程是系统进行资源和调度的一个独立单位,拥有系统资源。 image.png

死锁

多线程中出现资源争用现象,导致相互阻塞。

Binder

Android底层的一种进程间通信方式。Android中四大组件的通信底层都依赖于Binder IPC。

ANR原因

产生ANR的直接原因是组件执行超时,而组件产生超时的原因是应用的主进程执行了耗时任务或者被阻塞。 image.png

主线程IO

在输入事件中执行文件读写操作(耗时超过5S),重复点击两次触发ANR image.png log直接输出ANR的原因。 image.png

内存紧张

cpu总共被使用99%

image.png

定位问题

严格模式

StrictMode是一个可以检测线程中耗时行为的工具,当检测到问题时回以弹窗或者日志提示开发者关注问题。

image.png StrictMode 最常用于捕获应用程序主线程上的意外磁盘或网络访问,其中接收 UI 操作并发生动画。使磁盘和网络操作远离主线程可以使应用程序更加流畅、响应速度更快。

在application或者activity的onCreat中添加如下代码,StrictMode支持探测代码中网络请求、文件读写等耗时操作

image.png

  • setThreadPolicy:设置应检测当前线程上的哪些操作的策略以及哪些惩罚。
  • setVmPolicy:设置应检测 VM 进程(在任何线程上)中的哪些操作的策略及惩罚。 

StrictMode 不是一种安全机制,不能保证找到所有磁盘或网络访问。虽然它在进行 Binder 调用时会跨进程边界传播其状态,但它最终仍然是一种尽力而为的机制。需要注意的是来自 JNI 调用的磁盘或网络访问不一定会触发它

Android Profiler

developer.android.com/studio/prof…

Trace文件

导出anr文件命令

  1. adb bugreport
  2. adb pull data/anr/traces.txt ~/your path/traces.txt

经验总结

  1. 绝大部份情况都是因为主线程执行任务耗时而导致的,先看Trace文件的主线程中正在执行的任务,再根据mapping文件映射到我们的代码中,再定位具体耗时的那一行代码。
  2. 系统服务超时会导致ANR,我们可以看下trace中是否包含BinderProxy.transactNative关键字
  3. 还有一些trace上的堆栈上看不出什么问题,先看下cpu使用情况,我们需要关注cpu使用情况的最后一行TOTAl use,如下图cpu总共被使用99%,这时候发上ANR也不足为奇了。  

参考

  1. developer.android.com/topic/perfo…
  2. developer.android.com/reference/a…
  3. segmentfault.com/a/119000004…