浅析 Android 系统稳定性中应用程序 ANR 无响应的原因

Posted Android每日一讲

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了浅析 Android 系统稳定性中应用程序 ANR 无响应的原因相关的知识,希望对你有一定的参考价值。

稳定性问题简述

android稳定性是 Android 性能的一个重要指标,它也是 App 质量构建体系中最基本和最关键的一环;如果应用经常崩溃,或者关键功能不可用,那显然会对我们的留存产生重大影响

所以为了保障应用的稳定性,我们首先应该树立对稳定性的正确认识

从表现来看有:

  • 死机重启
  • 自动关机
  • 无法开机
  • 冻屏
  • 黑屏
  • 闪退
  • 无响应

等等情况

这也就说明了稳定性问题比较杂,且很多是概率性问题,没有统一处理方式需要针对具体的问题,具体分析

一般来说:必现的问题较易解决,针对当前代码添加各种调试 log ,一步步 debug 去定位,过程虽然可能慢点,但一般都会解决

针对偶发性概率问题,则较为麻烦,依赖于大量的测试复现,然后统计 分析当前抓取到的 events 、system 等 log 中,找到复现的步骤,然后去定位;且针对与这种概率问题,最好能够拿到当时的现场,所以有时候需要将 tombstone 或者 ANR 、crash 转为 ANR 去处理

从技术层面来划分:

无外乎两大类:长时间无法执行完成(Timeout) 以及异常崩溃(crash). 主要分类如下所示:

  • ANR
  • Watchdog
  • Crash、界面、流程异常
  • Tombstone
  • Panic

接下来我们细说一下 ANR

应用程序无响应即 Application not Responding ,简称“无响应”或 “ANR”

为什么会有 ANR?

如上所述,ANR 的产生需要同时满足三个条件

  • 主线程: 只有应用程序进程的主线程响应超时才会产生 ANR
  • 超时时间: 产生 ANR 的上下文不同,超时时间也会不同,但只要在这个时间上限内没有响应就会 ANR
  • 输入事件/特定操作: 输入事件是指按键、触屏等设备输入事件,特定操作是指 BroadcastReceiver 和 Service 的生命周期中的各个函数,产生 ANR 的上下文不同,导致 ANR 的原因也会不同

ANR 机制本身就是为了防止差的用户体检,是完全 Android 系统工程师为大家埋下的雷;这个既然是工程师设计的,那就可以被工程师控制

  • 比如像我们通常说按键 5s 内时间处理不完的 ANR ,这个 5s 在一些低端手机上被修改为 8s 甚至 10s ,还有就是 ANR 产生后,相关的“现场”是会被保留下来

  • 比如在 events log、main log、system log 上有相关的 ANR 信息;再比如出现 ANR 的时候生成的 trace 文件,bugreport 中也有一些有用的信息,帮我们分析 ANR 产生的原因

现在好多平台 cpu 都是多核cpu 达到 100%不能说明就是系统卡顿导致的 ANR

还要说明,系统 ANR in 往往比 event log 中的 am_anr很多;具体慢多少需要根据场景而定,所以建议以 event log 中的 am_anr 作为时间窗口起点比较好

那ANR in 能看到哪些信息呢?

  • Reason: ANR 原因,这个在 evnent log 中也可以看到作用不大;原因可以定位 ANR 的时间窗口,比如按键类型的 ANR 那分析的时候只需要在 event log 的am_anr 之前 5s 的时间窗口中分析就行
  • Load: 0.06 / 0.05 / 0.05 cpu 负载,这个可以看到是否是系统性能整体慢的参考指标。但是各个平台这个参数又不统一。所以参考价值不大
  • TOTAL: 这个是整体 cpu 占用情况如果能够看到 kernel 占用比较多,可以考虑是否是系统问题

那如何证明系统卡顿导致的 ANR 呢?

如果是由系统引起的卡顿event log 中搜索dvm_lock_sample,因为往往在系统卡顿的时候
dvm_lock_sample 会打印出系统主线程的一些主要方法耗费了多少时间

  • dvm_lock_sample: [system_server,1,Binder:1614_A,22,AlarmManagerService.java,1072,-,2496,4]
    (进程名,是否主线程1是0否,线程号,花费时间,文件名,申请锁行数,持锁文件名,持锁行数,采样频率)

今天关于 ANR 的相关技术知识点就分享到这里了;关于 ANR 的技术问题,我们还要去好好的学习剖析;因此我把工作中遇到的性能卡顿问题,以及对网上大部分的资料的收集和整理,最终整合出了一份 《Android 高工必备性能优化》学习文档,有需要这份文档的朋友,可以 私信 发送 “进阶” 即可 免费获取

内容展示如下:

Android 高工必备性能优化 目录:

UI 布局优化
  • 优化思路
  • 优化方案
  • 选择合适的布局类型
  • 尽可能少用 wrap_content
  • 用 SurfaceView 或 TextureView 代替普通 View
  • 使用 Renderjavascript
  • 使用 OpenGL 绘图
  • 布局调优工具

完整版 Android 高工必备性能优化 学习文档获取方式:可以 私信 发送 “进阶” 即可 免费获取
卡顿优化和布局优化
  • 卡顿分析
  • 刷新率
  • PerfDog
  • CPU Profile
  • 布局优化
  • 过度绘制
  • 解决过度绘制
  • 层级优化
  • 使用 merge
  • ViewStub
  • 不要在 onDraw 里创建对象
  • 异步加载布局

崩溃优化
  • 崩溃的收集
  • ANR
  • 应用退出
  • 崩溃处理
  • 崩溃现场
  • 崩溃分析
  • 系统崩溃

完整版 Android 高工必备性能优化 学习文档获取方式:可以 私信 发送 “进阶” 即可 免费获取
网络优化
  • 网络指标
  • 用户体验
  • 网络监控
  • Network Monitor
  • Charles 抓包工具
  • 优化 DNS 解析
  • 连接池复用
  • 数据压缩
  • 弱网优化
  • 网络安全

储存优化
  • Android 存储方式
  • SharedPrefence
  • 多进程问题 -> mmkv
  • 已经有 xml/json,为什么要用 protobuf
  • 项目中使用 protobuf
  • 语言规范
  • 字段约束
  • 编码协议

由于篇幅有限,资料就不做完全展示了;有需要这份 《Android 高工必备性能优化》 学习文档 的朋友,可以 私信 发送 “进阶” 即可 免费获取

技术是无止境的,你需要对自己提交的每一行代码、使用的每一个工具负责,不断挖掘其底层原理,才能使自己的技术升华到更高的层面

加油!各位 Android 开发者们

系统稳定性 - 测试2.2 谈谈Monkey老化测试场景的ANR问题分析

Monkey 测试,就像一只猴子在屏幕上随即点击测试。Andoird通过 Monkey 向系统发送伪随机的用户事件流(点击、滑动、 Application 切换、横竖屏、应用关闭)实现对正在开发的应用程序进行压力测试,检测程序 多久的时间会发生异常。monkey 测试为了测试软件的稳定性而生,在有些公司称之为老化测试。

Monkey测试是随机的,不可自定义;但频率可控,测试过程中可能会导致的不必要的应用 crash 或者 ANR。

一,同时进行两组或多组Monkey测试同时进行

这种情况下会导致事件触发过快,事件处理速度异常通常会导致 SystemServe 的 ION 内存占用高。这种问题在大分辨率的设备会很容易导致内存异常。可以通过dumpsys pid_xxx查看进程的详细内存布局;

二,Monkey机制问题

如果 monkey 测试过程中由于其他应用 crash 或者 ANR,系统触发异常处理机制,打印 Log,处理 crash 进程等操作,会使得系统瞬间非常卡顿。这样通过 Monkey 向系统发送伪随 机的用户事件流,由于系统卡顿,可能会导致例如,AMS 广播队列阻塞,time tick 广播未能 及时分发完成等情况,导致被测试应用出现 crash 或者 ANR 情况。

如下场景:

D KeyguardUpdateMonitor: received broadcast android.intent.action.TIME_TICK

TIME_TICK 广播由系统发送至 应用 的过程整体慢导致,应用接收到广播时已经慢了 20s+,已经超出了前台广播的处理时间限制(前台广播接收处理的总时限为 20s),直接就会触发 ANR。

三&#

以上是关于浅析 Android 系统稳定性中应用程序 ANR 无响应的原因的主要内容,如果未能解决你的问题,请参考以下文章

面试系列——App稳定性问题分析总结

面试系列——App稳定性问题分析总结

系统稳定性 - 测试2.2 谈谈Monkey老化测试场景的ANR问题分析

Android ANR全解析&华为AGC性能管理解决ANR案例集

Android ANR优化 1

Android ANR的产生与分析