上帝说要有ANR,于是Bugly就有了ANR上报。那么ANR究竟是什么?

近期非常多童鞋问起精神哥ANR的问题,那么这次就来聊一下,鸡爪怎么泡才好吃。噢不,是怎样高速定位ANR。

ANR是什么

简单说,通常就是App执行的时候,duang~卡住了。怎么搞都动不了。

当卡住超过一定时间。Android系统觉得这就是一次“ANR(Application Not Responding)”。

详细说。在下面情况发生时,会发生ANR(可能在不同ROM 中时间有所更改):

  • 用户的输入在5s内没被App响应。

  • BroadcastReceiver的onReceiver()超过10s;

  • Service中各生命周期函数运行超过20s。


ANR必须死

用户在App的绝大部分操作,都须要有App的主动回应。比方按下button之后button样式的改变、下拉滚动栏内容的移动、载入资源时的菊花转转转,它们都是“操作-反馈”配对的模式。对于我们手机上最常见的触摸操作。0.1s的响应延迟已经有非常明显的卡顿感了。而对于常见的ANR。用户至少要等5s以上!

发生了ANR,往往会弹出对话框,问用户是继续等待还是直接关掉:

相信差点儿全部Android手机用户都见过这个然并卵的ANR对话框,但大部分普通用户根本不知道这个对话框在讲什么,而且往往也仅仅有关闭App。

漫长的等待就给我看这个?从用户的体验看,就是心中一万仅仅草泥马奔腾起来撞火车的感受。可见ANR对于应用的影响并不亚于Crash。

一般来说,界面相对越不“流畅”的App(说明UI线程耗时操作多)越easy发生ANR(一个输入事件在某个设备A上4秒有了反馈。并不意味着它在其它设备B上是安全的)。

ANR事实上就是界面卡顿的极端情况。反过来,仅仅要通过合理的方案消灭了App出现的ANR,往往也同一时候会使App展示界面表现会更加顺滑流畅。

一些典型的ANR 问题场景

这里举几个easy发生ANR的场景:

1)最常见的错误,UI线程等待其他线程释放某个锁,导致UI线程无法处理用户输入。

2)游戏中每帧动画都进行了比較耗时的大量计算,导致CPU忙只是来;

3)Web应用中。网络状态不稳定。而界面在等待网络数据;

4)UI线程中进行了一些磁盘IO(包含数据库、SD卡等等)的操作。在个别设备上由于硬件损坏等原因堵塞住了;

5)手机被其它App占用着CPU。自己获取不到足够的CPU 时间片,纯属误伤。

通过ANR 日志定位问题

当ANR发生时。我们往往通过Logcat和traces文件(文件夹/data/anr/)的相关信息输出去定位问题。主要包括下面几方面:

1)基本信息,包含进程名、进程号、包名、系统build号、ANR 类型等等;

2)CPU使用信息。包含活跃进程的CPU 平均占用率、IO情况等等。

3)线程堆栈信息。所属进程包含发生ANR的进程、其父进程、近期有活动的3个进程等等。

这里举个简单的样例(实际上由于各App所处环境各异,可能出现各种各样复杂的ANR情况)当App执行卡住,弹出ANR对话框。查看Logcat输出:

ActivityManager: ANR in com.tencent.bugly.demo (com.tencent.bugly.demo/.MainActivity)
ActivityManager: PID: 18617
ActivityManager: Reason: Input dispatching timed out (Waiting because the touched window has not finished processing the input events that were previously delivered to it.)
ActivityManager: Load: 18.42 / 18.09 / 18.29
ActivityManager: CPU usage from 5924ms to 475ms ago:
ActivityManager: 93% 18617/com.tencent.bugly.demo: 93% user + 0% kernel / faults: 75 minor
……
ActivityManager: CPU usage from 2906ms to 3429ms later:
ActivityManager: 96% 18617/com.tencent.bugly.demo: 96% user + 0% kernel
……
ActivityManager: 55% TOTAL: 51% user + 3.8% kernel

分析一下,从Logcat能够得到下面信息:

  1. com.tencent.bugly.demo这个App的MainActivity发生了ANR,进程号18617;

  2. ANR原因:用户输入超时。

  3. ANR发生前、后一段时间分别附在情况:在ANR发生前后,CPU有90+%耗费在这个demo上,说明非常可能是这个demo自身性能引起的。

接下来再看traces文件确认:

----- pid 18617 at xxxx -----
Cmd line: com.tencent.bugly.demo
JNI: CheckJNI is off; workarounds are off; pins=0; globals=272 (plus 2 weak)
DALVIK THREADS:
"main" prio=5 tid=1 SUSPENDED
| group="main" sCount=1 dsCount=0 obj=0x415e4e58 self=0x415d3028
| sysTid=18617 nice=0 sched=0/0 cgrp=apps handle=1074372948
| state=S schedstat=( 38588000572 591063492 5767 ) utm=3846 stm=12 core=0
at com.tencent.bugly.demo.MainActivity$3.doCalc(MainActivity.java:~38)
at com.tencent.bugly.demo.MainActivity$3.onClick(MainActivity.java:33)
……

分析一下,traces文件里包括下面信息:

1、进程号:18617;包名:com.tencent.bugly.demo。

2、发生ANR时,main线程被挂起(也可能是其它等待状态,比方TIMED_WAIT);

3、线程的几个重要參数:

  • group:线程组名称“main”;

  • sCount:Suspended个数“1”。

  • obj:线程的Java对象地址。

  • self:线程的Native对象地址;

  • sysTid:线程号(这里主线程的线程号=进程号)“18617”。

4、详细堆栈:从堆栈能够非常清晰看出是doCalc()方法出的问题,由onClick触发。

综合以上分析。问题还原为:com.tencent.bugly.demo这个App的MainActivity中有个耗时的doCalc方法在跑。无法响应用户的触摸或按键输入。OK。接下来在代码里找问题就好了。

怎样解决ANR

当然是尽可能降低UI线程的耗时操作。以及BroadcastReceiver、Service生命周期中的标准回调方法啦。

Android官方文档建议:

1)使用AsyncTask类,能够非常方便地实现子线程耗时操作与UI更新;

2)对于BroadcastReceiver的耗时操作。建议放到Service中运行。

3)对于自建的Thread,能够通过Handler使之与UI 线程通信(这里须要注意的是。Thread默认优先级和UI线程是一样的,建议设置一般线程优先级为Process.THREAD_PRIORITY_BACKGROUND)。

这些方案大家应该都知道。只是仍难免有大量的ANR是写代码时忽略了,在測试时没发生,终于在用户的手机上出现的。回忆一下是不是都经历过用户会反馈“App卡死没反应了”。但开发GG客服MM们却又由于缺少日志或无法复现而束手无策?因此要修复ANR。首先是要能发现用户ANR了。而且能知道是哪段代码导致ANR了,这样才干谈修复。

为了帮助广大开发人员解决这一难题,腾讯Bugly针对iOS的卡顿及Android的ANR提供监測服务即将上线,协助开发人员轻松定位问题。

【腾讯bugly干货分享】精神哥手把手教你怎样智斗ANR的更多相关文章

  1. 【腾讯Bugly干货分享】微信终端跨平台组件 Mars 系列 - 我们如约而至

    导语 昨天上午,微信在广州举办了微信公开课Pro.于是,精神哥这两天的朋友圈被小龙的"八不做"刷屏了.小伙伴们可能不知道,下午,微信公开课专门开设了技术分论坛.在分论坛中,微信开源 ...

  2. 【腾讯Bugly干货分享】程序员们也该知道的事——“期权和股票”

    本文来自于腾讯Bugly公众号(weixinBugly),未经作者同意,请勿转载,原文地址:https://mp.weixin.qq.com/s/pfj9NLLuKYAfJJF84R9WAw 作者:B ...

  3. 【腾讯Bugly干货分享】聊聊苹果的Bug - iOS 10 nano_free Crash

    本文来自于腾讯Bugly公众号(weixinBugly),未经作者同意,请勿转载,原文地址:https://mp.weixin.qq.com/s/hnwj24xqrtOhcjEt_TaQ9w 作者:张 ...

  4. 【腾讯Bugly干货分享】跨平台 ListView 性能优化

    本文来自于腾讯Bugly公众号(weixinBugly),未经作者同意,请勿转载,原文地址:https://mp.weixin.qq.com/s/FbiSLPxFdGqJ00WgpJ94yw 导语 精 ...

  5. 【腾讯Bugly干货分享】让 CodeReview 这股清流再飞一会儿

    本文来自于腾讯Bugly公众号(weixinBugly),未经作者同意,请勿转载,原文地址:https://mp.weixin.qq.com/s/ToYeT4Y4pzx0ii9Z92fo-Q 作者:刘 ...

  6. 【腾讯Bugly干货分享】打造“微信小程序”组件化开发框架

    本文来自于腾讯Bugly公众号(weixinBugly),未经作者同意,请勿转载,原文地址:http://mp.weixin.qq.com/s/2nQzsuqq7Avgs8wsRizUhw 作者:Gc ...

  7. 【腾讯Bugly干货分享】总结一个技术总监的教训和经验

    本文来自于腾讯Bugly公众号(weixinBugly),未经作者同意,请勿转载,原文地址:http://mp.weixin.qq.com/s/Ry-G0Nikh6m-h3ZVC2cLyQ 导语 20 ...

  8. 【腾讯Bugly干货分享】职场中脱颖而出的成长秘诀

    本文来自于腾讯Bugly公众号(weixinBugly),未经作者同意,请勿转载,原文地址:http://mp.weixin.qq.com/s/uQKpVg7HMLfogGzzMyc9iQ 导语 时光 ...

  9. 【腾讯Bugly干货分享】OCS——史上最疯狂的iOS动态化方案

    本文来自于腾讯Bugly公众号(weixinBugly),未经作者同意,请勿转载,原文地址:https://mp.weixin.qq.com/s/zctwM2Wf8c6_sxT_0yZvXg 导语 在 ...

随机推荐

  1. hihoCoder #1471 拥堵的城市

    这道题目是hihoCoder Challenge 27的C题,我考虑了5天:(. 计数问题.由于树的结构的特殊性(树具有递归结构),不难想到思路是树形DP.由于这是[计数问题]而非[优化问题],我们思 ...

  2. POJ 3581 Sequence ——后缀数组 最小表示法

    [题目分析] 一见到题目,就有了一个显而易见obviously的想法.只需要每次找到倒过来最小的那一个字符串翻转就可以了. 然而事情并不是这样的,比如说505023这样一个字符串,如果翻转了成为320 ...

  3. System.out.println()和System.out.write()的区别

    这两个函数一个是System.out.write()输出字符流,System.out.println()是输出字节流,很简单.看下面这个程序就明白了.     //import java.util.* ...

  4. 素数判定 2(codevs 1702)

    题目描述 Description 一个数,他是素数么? 设他为P满足(P<=263-1) 输入描述 Input Description P 输出描述 Output Description Yes ...

  5. 理解 virbr0

    virbr0 是 KVM 默认创建的一个 Bridge,其作用是为连接其上的虚机网卡提供 NAT 访问外网的功能. virbr0 默认分配了一个IP 192.168.122.1,并为连接其上的其他虚拟 ...

  6. Java Interface 是常量存放的最佳地点吗?(转帖学习,非原创)

    Java Interface 是常量存放的最佳地点吗?(转帖学习,非原创) 由于java interface中声明的字段在编译时会自动加上static final的修饰符,即声明为常量.因而inter ...

  7. EMD距离

    一.场景介绍   最近在研究一个场景:图片质量评分,给一张图片一个预测的分数.   里面提到了用 EMD(Earth Mover’s Distance)算法来评估两张图片之间的分布距离.下面主要讲解下 ...

  8. Python入门--8--现在需要先学习可视化--包:easygui

    一.安装.了解easygui 下载地址:http://bbs.fishc.com/forum.php?mod=viewthread&tid=46069&extra=page%3D1%2 ...

  9. 使用 ftrace 调试 Linux 内核,第 2 部分

    ftrace 操作概述 使用 ftrace 提供的跟踪器来调试或者分析内核时需要如下操作: 切换到目录 /sys/kernel/debug/tracing/ 下 查看 available_tracer ...

  10. PAT (Advanced Level) 1086. Tree Traversals Again (25)

    入栈顺序为先序遍历,出栈顺序为中序遍历. #include<cstdio> #include<cstring> #include<cmath> #include&l ...