作者:友盟+移动开发专家 张文

「崩溃」与「卡顿」、「异常退出」等一样,是影响App稳定性常见的三种情况。相关数据显示,当iOS的崩溃率超过0.8%,Android的崩溃率超过0.4%的时候,活跃用户有明显下降态势。它不仅会造成关键业务中断、用户留存率下降、品牌口碑变差等负面影响,而且会直接带来卸载和流失。也同时给开发者带来不可小觑的资本损失。

那么,崩溃率低的App质量就高么?是否可以通过崩溃率直接判断App的稳定性?

首先,衡量一个App质量好坏时我们需要定义一个统一的口径,即哪些指标可以作为稳定性的评估口径?以友盟+的U-APM定义的稳定率这个概念为例,评价一个App的稳定性和质量,一般从以下三点综合考虑:

发生了崩溃,如java崩溃和Native崩溃,即用崩溃率这个指标来评估计算;

发生了ANR,即用ANR率这个指标来评估计算;

异常退出,如:low memory killer、任务列表中划掉、系统异常、断电、用户触发关机/重启等,即用异常率这个指标来评估计算。

崩溃,也就是程序出现异常,导致程序退出。包括:

Java崩溃,也就是在Java代码中出现了未捕获异常,导致程序异常退出。如:空指针异常、数组越界异常等。

Native异常,也就是在Native代码中,出现错误产生相应的signal信号,导致程序异常退出。如:访问非法地址、地址对其问题等。

Java崩溃的捕获相对会简单一些,Native崩溃的捕获可能要求我们对系统底层知识要有一定的掌握。我们知道Android是基于Linux系统的,系统中的崩溃大多是由于编码错误或硬件错误导致的。当系统遇到不可恢复的错误时会通过异常中断的方式触发异常处理流程,这些中断的处理被统一为了信号量。当应用程序接收到某个信号量时会按照内核默认的动作处理,如Term、lgn、Core、Stop、Cont。同时我们也可以通过sigaction注册接收信号来指定处理动作,比如捕获崩溃信息等。当然捕获过程中也会有一些困难点,尤其在极端环境中,比如栈溢出时,由于栈空间已经被用完,造成我们的信号处理函数没法被调用,以至于无法捕获到崩溃信息,这时我们需要考虑使用signalstack,使我们的信号处理函数可以在堆里面分配到一块内存空间作为“可替换信号栈”来处理崩溃信息。

当然,除了稳定、安全的捕获能力外,还需要丰富崩溃现场的上下文信息,比如Logcat信息、调用栈信息、设备信息、环境信息等等,为我们后续定位和解决问题提供全面的参考。

对于发生崩溃的情况,我们使用崩溃率作为数据指标。包括:

UV崩溃率,也就是发生崩溃错误的去重用户/去重活跃总用户;

PV崩溃率,也就是发生崩溃错误的次数/启动次数;

启动崩溃率,也就是应用启动过程中发生的崩溃,很容易被忽略但又非常重要的崩溃指标,因为启动是APP生命周期中非常重要的一个阶段,很多广告、闪屏、活动等内容都在这个过程中透出,同时启动时又需要加载各种初始化,并且如果启动出现错误,往往热修复、降级融灾策略都无法弥补。

ANR,也就是Application Not Responding,当应用程序一段时间无法及时响应,则会弹出ANR对话框,让用户选择继续等待,还是强制关闭。从用户体验的角度看,有时候ANR可能要比崩溃会带来更糟糕的体验,所以开发者重视崩溃的同时也要非常重视ANR。

ANR捕获的准确性一直是不断升级打怪、不断完善的过程。早期我们通过FileObserver 监听/data/anr/traces.txt文件的变化进行捕获和上报,但很遗憾随着版本升级,系统和厂商开始收紧系统文件但权限,此方案的覆盖设备情况越来越低,造成ANR捕获的准确性也一直降低。

随后我们改进为监控消息队列的运行时间的方式捕获ANR,也就是向主线程Looper中放入一个空消息,监听该空消息在5秒后是否被执行,但该方案无法真实的捕获ANR情况(存在漏报和误报情况),并且也无法得到完整的ANR内容。后续我们参考Android ANR的实现原理,实现了一套实时、准确的ANR捕获方案,并且可以兼容所有系统版本。我们知道系统的system_server 进程在检测到 APP 出现 ANR 后,会向出现ANR 的进程发送 SIGQUIT (signal 3) 信号。默认情况,系统的 libart.so 会收到该信号,并调用 Java 虚拟机的 dump 方法生成 traces。

我们通过拦截SIGQUT,在出现ANR时优先接收到信号,并生成traces和ANR日志,在处理完信号后,将信号继续传递给系统让系统生成traces文件,生成traces文件时,在保证内容与系统原生的一致性的同时还对生成traces文件的速度进行了明显的提升,有效地避免了可能因生成 traces 时间过长,而被 system_server 使用 SIGKILL (signal 9) 再次强杀,同时我们对捕获到的内容进行了丰富,包括:触发 ANR 的原因、手机中 TOP 进程CPU 使用率、ANR 进程中 TOP 线程 CPU 使用率、CPU 各核心处理时间分布情况、磁盘 IO 操作等待时长等重要信息,对分析、定位和解决 ANR 问题,提供了更加强有力的支撑!

同样对于发生ANR的情况,我们也分为UV ANR率和PV ANR率,算法可参考如上崩溃率的计算。

当然,除了崩溃和ANR,我们往往忽略了异常退出这种场景,但往往通过异常退出我们可以发现如low memory killer、系统重启等无法正常捕获到的问题。比如兼容性问题导致的闪退、设备重启、三方库主动调用exit函数,导致应用闪退次数增加等难以发现的问题,所以通过异常退出率我们可以比较全面的了解和衡量应用的稳定性。

综上,对于文章开始的那个问题,我想大家都应该有答案了吧。当然,我们不应该为了掩盖代码质量问题,通过手动try catch去规避某些问题,这样有可能会打断用户的正常使用,并造成感知性的阻断反馈,应该从用户使用APP时的真实感知出发,当出现问题时及时捕获和处理问题。

App的稳定性时一个长期不断迭代的过程,在这个过程中U-APM是一个很好的提升效率降低成本的工具,他提供了收集、解析、聚合、分析的能力,下一期我们会从如何通过U-APM解决和处理崩溃、ANR等问题进行讲解,尽情期待。

扫盲贴|如何评价一款App的稳定性和质量?的更多相关文章

  1. iOS设计 - 一款APP从设计稿到切图过程概述

    这篇文章站在GUI设计师的角度概述了APP从项目启动到切片输出的过程,相当于工作流程的介绍.这里写的不是一种规范,只是一种工作方法,加上技术的更新是非常快的,大家在具体工作中,一定要灵活运用. 这里我 ...

  2. js判断移动端是否安装某款app的多种方法

    本文实例讲解了js判断移动端是否安装某款app的多种方法,分享给大家供大家参考,具体内容如下 第一种方法: 一:判断是那种设备 ? || u.indexOf(; //android终端或者uc浏览器 ...

  3. 关于工伤事故索赔计算很好用的一款APP

    关于工伤事故索赔计算很好用的一款APP.详细介绍工伤伤残等级评估 工伤计算器根据国家颁布<劳动能力鉴定 职工工伤与职业病致残等级>,通过关键字检索,快速评估工伤伤残等级. 软件说明:  1 ...

  4. fir.im Weekly - 如果让你重新做一款APP

    设想下:如果让你重新做一款 APP ,你会用到哪些开发.设计等资源和工具? 本期的 Weekly 为大家分享了最近不错的 APP 开发资源,大部分是关于 iOS 开发. Android 开发.UI设计 ...

  5. 开发者必知的8款App快速开发工具

    开发者必知的8款App快速开发工具 “我有一个好创意,就差一个CTO……” “原生APP开发难度大,周期长,成本高,还没上线市场已经被占领了.” “APP版本迭代更新,都是企业的一道难关,没有一个一劳 ...

  6. 一款APP从设计稿到切图过程全方位揭秘 Mark

    纯干货!一款APP从设计稿到切图过程全方位揭秘   @BAT_LCK:我本身是一名GUI设计师,所以我只站在GUI设计师的角度去把APP从项目启动到切片输出的过程写一写,相当于工作流程的介绍吧.公司不 ...

  7. 工资不高也要给自己放假 这几款APP估计你用得上

    我是这样的一个人,我宁愿工资不高,只要给我足够的假期,那我就满足了.都说上班就是为了赚钱,但如果身体不好,赚再多的钱也是无福享受,所以建议各位,有机会的话,一定要抽出时间去旅游,去放松. 现在我们外出 ...

  8. 教育类APP开发现新增长,多款APP该如何突围?

    "十二五"以来,国家共出台相关的重大教育政策文件741个,而进入到"十三五"时期教育领域综合改革深入推进的关键期,不断促进教育现代化的实现.加快迈入人力资源强国 ...

  9. 如何设计一款APP,才能吸引用户眼球

    有APP分析机构研究表明,人们每天耗费在手机和平板上的平均时长为158分钟,其中127分钟是耗费在各类APP中,而仅有31分钟是花费在浏览网页上.随着人们对互联网的依赖性越来越强,移动APP发展迅速已 ...

随机推荐

  1. kubernetes进阶(四)服务暴露-ingress控制器之traefik

    上一章我们测试了在集群内部解析service名称, 下面我们测试在集群外部解析: 根本解析不到,因为我们外部用的dns是10.4.7.11,也就是我们的自建bind dns,这个DNS服务器上也没有响 ...

  2. vuepress & ReferenceError: window is not defined

    vuepress & ReferenceError: window is not defined bug Client Compiled successfully in 15.35s Serv ...

  3. Linux Bash Script loop

    Linux Bash Script loop shell 编程之流程控制 for 循环.while 循环和 until 循环 for var in item1 item2 ... itemN do c ...

  4. 2015 - 2020 最新 Linux 命令大全

    # 2015 - 2020 最新 Linux 命令大全 ## VIM 命令模式(Command mode):vi 插入模式(Insert mode):i底线命令模式(Last line mode):e ...

  5. GitHub Secrets All In One

    GitHub Secrets All In One https://docs.github.com/en/free-pro-team@latest/actions/reference/encrypte ...

  6. VIM 官方教程

    VIM 官方教程 zh-hans vim official documents https://www.vim.org/docs.php https://vimhelp.org/ translatio ...

  7. ES-Next & ES7 @decorator

    ES-Next & ES7 @decorator @decorator https://tc39.github.io/proposal-decorators/#sec-syntax https ...

  8. webpack defineConstants

    webpack defineConstants PAGES 全局常量/全局变量 https://webpack.js.org/plugins/define-plugin/ taro https://n ...

  9. cURL all in one

    cURL all in one convert http request to curl online https://curlbuilder.com/ https://cdn.xgqfrms.xyz ...

  10. TypeScript & Object Error

    TypeScript & Object Error Element implicitly has an 'any' type because expression of type 'any' ...