ANR产生的原因及定位分析

ANR全称是Application Not Responding,意思是应用程序无响应。相信从事Android开发的肯定遇到过。ANR的直观体验是用户在操作App的过程中,感觉界面卡顿,当界面卡顿超过一定时间(一般5秒),就会出现ANR对话框。ANR对于一个应用来说是不能承受之痛,其影响并不比应用发生Crash小。

ANR产生的原因

只有当应用程序的UI线程响应超时才会引起ANR,超时产生原因一般有两种。

  • 当前的事件没有机会得到处理,例如UI线程正在响应另一个事件,当前事件由于某种原因被阻塞了。
  • 当前的事件正在处理,但是由于耗时太长没能及时完成。

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

KeyDispatchTimeout

最常见的一种类型,原因就是View的点击事件或者触摸事件在特定的时间(5s)内无法得到响应。

BroadcastTimeout

原因是BroadcastReceiver的onReceive()函数运行在主线程中,在特定的时间(10s)内无法完成处理。

ServiceTimeout

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

典型的ANR问题场景

  • 应用程序UI线程存在耗时操作。例如在UI线程中进行联网请求,数据库操作或者文件操作等。
  • 应用程序的UI线程等待子线程释放某个锁,从而无法处理用户的输入。
  • 耗时的动画需要大量的计算工作,可能导致CPU负载过重。

ANR的定位和分析

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

Cmd line: com.anly.githubapp  // 最新的ANR发生的进程(包名)

...

DALVIK THREADS (41):
"main" prio=5 tid=1 Sleeping
  | group="main" sCount=1 dsCount=0 obj=0x73467fa8 self=0x7fbf66c95000
  | sysTid=2976 nice=0 cgrp=default sched=0/0 handle=0x7fbf6a8953e0
  | state=S schedstat=( 0 0 0 ) utm=60 stm=37 core=1 HZ=100
  | stack=0x7ffff4ffd000-0x7ffff4fff000 stackSize=8MB
  | held mutexes=
  at java.lang.Thread.sleep!(Native method)
  - sleeping on <0x35fc9e33> (a java.lang.Object)
  at java.lang.Thread.sleep(Thread.java:1031)
  - locked <0x35fc9e33> (a java.lang.Object)
  at java.lang.Thread.sleep(Thread.java:985) // 主线程中sleep过长时间, 阻塞导致无响应.
  at com.tencent.bugly.crashreport.crash.c.l(BUGLY:258)
  - locked <@addr=0x12dadc70> (a com.tencent.bugly.crashreport.crash.c)
  at com.tencent.bugly
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值