ANR产生原因:
1、View的按键事件或者触摸事件在特定的时间(5秒)内无法得到响应。
2、BroadcastReceiver的onReceive()方法运行在主线程中,在特定的时间(10秒)内无法完成处理。
3、Service的各个生命周期函数在特定的时间(20秒)内无法完成处理。
定位和分析:
首先查看Logcat日志信息可知一些信息:
07-22 21:39:17.019 819-851/? E/ActivityManager: ANR in com.xxxx.xxx.performance (com.xxxx.xxx.performance/.view.home.activity.MainActivity)
PID: 7398
Reason: Input dispatching timed out (com.xxxx.xxx.performance/com.xxxx.xxx.performance.view.home.activity.MainActivity, Waiting to send non-key event because the touched window has not finished processing certain input events that were delivered to it over 500.0ms ago. Wait queue length: 29. Wait queue head age: 8579.3ms.)
Load: 18.22 / 18.1 / 18.18
CPU usage from 0ms to 8653ms later:
124% 7398/com.xxxx.xxx.performance: 118% user + 6.5% kernel / faults: 4962 minor 7 major
82% 819/system_server: 28% user + 53% kernel / faults: 10555 minor 11 major
23% 4402/adbd: 1% user + 22% kernel
10% 996/com.android.systemui: 4.6% user + 6.2% kernel / faults: 4677 minor 1 major
4.6% 2215/com.android.phone: 1.5% user + 3.1% kernel / faults: 5411 minor
6.3% 6268/perfd: 3.4% user + 2.8% kernel / faults: 134 minor
0.5% 1149/com.miui.whetstone: 0.1% user + 0.3% kernel / faults: 3016 minor 1 major
0.2% 2097/com.xiaomi.finddevice: 0.1% user + 0.1% kernel / faults: 2256 minor
0.6% 2143/com.miui.daemon: 0.2% user + 0.3% kernel / faults: 2798 minor
1.2% 1076/com.xiaomi.xmsf: 0.6% user + 0.6% kernel / faults: 2802 minor
0% 2122/com.android.server.telecom: 0% user + 0% kernel / faults: 2929 minor
0% 2244/com.miui.contentcatcher: 0% user + 0% kernel / faults: 1800 minor
0% 2267/com.mediatek.nlpservice: 0% user + 0% kernel / faults: 2052 minor
0% 2166/com.xiaomi.mitunes: 0% user + 0% kernel / faults: 1797 minor 3 major
0% 2190/com.fingerprints.service: 0% user + 0% kernel / faults: 1857 minor
0.1% 154/mmcqd/0: 0% user + 0.1% kernel
0.4% 8069/logcat: 0.3% user + 0.1% kernel
0.3% 58/cfinteractive: 0% user + 0.3% kernel
0.3% 153/mtk charger_hv_: 0% user + 0.3% kernel
0% 3387/mcd: 0% user + 0% kernel / faults: 5 minor
0.3% 7828/kworker/0:1: 0% user + 0.3% kernel
0.2% 130/frame_update_wo: 0% user + 0.2% kernel
0.2% 4945/com.xiaomi.gamecenter: 0.2% user + 0% kernel
0.2% 27293/kworker/u16:2: 0% user + 0.2% kernel
0% 7/migration/0: 0% user + 0% kernel
0.1% 8/rcu_preempt: 0% user + 0.1% kernel
0% 23/migration/4: 0% user + 0% kernel
0% 27/migration/5: 0% user + 0% kernel
0% 31/migration/6: 0% user + 0% kernel
0.1% 95/hps_main: 0% user + 0.1% kernel
0% 124/display_esd_che: 0% user + 0% kernel
0% 131/disp_idlemgr: 0% user + 0% kernel
0.1% 167/Atmel_mxt_ts: 0% user + 0.1% kernel
0% 289/mediaserver: 0% user + 0% kernel
0.1% 770/gsm0710muxd: 0% user + 0.1% kernel
0% TOTAL: 0% user + 0% kernel + 0% softirq
CPU usage from 7486ms to 8021ms later:
120% 7398/com.xxxx.xxx.performance: 118% user + 1.8% kernel / faults: 322 minor
98% 7398/yun.performance: 98% user + 0% kernel
9.2% 8088/RxComputationTh: 5.5% user + 3.7% kernel
5.5% 7622/RxComputationTh: 3.7% user + 1.8% kernel
5.5% 7955/RxComputationTh: 3.7% user + 1.8% kernel
75% 996/com.android.systemui: 31% user + 44% kernel / faults: 1416 minor 1 major
74% 1017/Signal Catcher: 27% user + 46% kernel
28% 819/system_server: 9.4% user + 18% kernel / faults: 37 minor
9.4% 1301/Binder_9: 3.7% user + 5.6% kernel
9.4% 1314/Binder_A: 3.7% user + 5.6% kernel
5.6% 851/ActivityManager: 0% user + 5.6% kernel
24% 4402/adbd: 0% user + 24% kernel
24% 4402/adbd: 0% user + 24% kernel
1.8% 6207/adbd: 1.8% user + 0% kernel
5.6% 6268/perfd: 1.8% user + 3.7% kernel / faults: 10 minor
3.7% 6276/Studio:PollCpu: 0% user + 3.7% kernel
3.7% 6358/perfd: 3.7% user + 0% kernel
1.8% 7996/perfd: 1.8% user + 0% kernel
0.9% 23/migration/4: 0% user + 0.9% kernel
+0% 8260/dumpsys: 0% user + 0% kernel
0% TOTAL: 0% user + 0% kernel + 0% iowait + 0% softirq
问题出现的类名包名是:com.xxxx.xxx.performance.view.home.activity.MainActivity
进程PID为:7398
产生原因是: Input dispatching timed out
活跃进程CPU占用率: 124% 7398/com.xxxx.xxx.performance
82% 819/system_server
10% 996/com.android.systemui
4.6% 2215/com.android.phone
…
通过查看Logcat日志只能知道以上的一些信息,并不能具体定位到代码行,知道具体问题所在、
对于进一步的信息只能通过ANR过程中生成的堆栈信息文件/data/anr/traces.txt来获得。
通过adb命令:adb shell
cat /data/anr/traces.txt >/mnt/sdcard/traces.txt
exit
将/traces.txt拷贝到sd卡里再获取分析:
----- pid 7398 at 2018-07-22 21:39:08 -----
Cmd line: com.xxxx.xxx.performance
ABI: arm64
可以知道ANR发生的时间、进程名、cpu架构
DALVIK THREADS (42):
"main" prio=5 tid=1 Native
| group="main" sCount=1 dsCount=0 obj=0x75ceafb8 self=0x55933ae7e0
| sysTid=7398 nice=0 cgrp=default sched=0/0 handle=0x7f7ddae0f0
| state=S schedstat=( 101485399944 3411372871 31344 ) utm=9936 stm=212 core=1 HZ=100
| stack=0x7fc8d40000-0x7fc8d42000 stackSize=8MB
| held mutexes=
......
at android.widget.TextView.setText(TextView.java:4082)
at android.widget.TextView.setText(TextView.java:3940)
at android.widget.TextView.setText(TextView.java:3915)
at com.xxxx.xxx.performance.view.home.fragment.AttendanceCheckInFragment.onNowTimeSuccess(AttendanceCheckInFragment.java:887)
线程名:main
线程优先级:prio=5
线程锁ID: tid=1
线程状态:Native
线程组名称: group=“main”
线程被挂起的次数:sCount=1
线程被调试器挂起的次数:dsCount=0
线程的java的对象地址:obj=0x75ceafb8
线程本身的Native对象地址:self=0x55933ae7e0
线程调度信息:
Linux系统中内核线程ID: sysTid=7398 ,与主线程的进程号相同
线程调度优先级:nice=0
线程调度组:cgrp=default
线程调度策略和优先级:sched=0/0
线程处理函数地址:handle=0x7f7ddae0f0
线程的上下文信息:
线程调度状态:state=S
线程在CPU中的执行时间、线程等待时间、线程执行的时间片长度:schedstat=( 101485399944 3411372871 31344 )
线程在用户态中的调度时间值:utm=9936
线程在内核态中的调度时间值:stm=212
最后执行这个线程的CPU核序号:core=1
线程的堆栈信息:
对战地址和大小:stack=0x7fc8d40000-0x7fc8d42000 stackSize=8MB
堆栈信息:可以找到ANR是在AttendanceCheckInFragment类里onNowTimeSuccess方法里setText方法导致的。
查看对应方法发现是因为频繁调用setText方法导致的,最终找到原因。