七猫Android安全模式的探索及实践

“安全模式”:App的启动保护实践。
App 启动期间连续崩溃时,客户端的分级执行策略。

背景&痛点&价值

对于一个商业项目而言,质量是研发同学的生命线。

试想一下,如果项目上线出现大面积的用户崩溃以及不可用,那简直是研发同学的噩梦。

这里有同学就要提问了:诸多大型商业项目在性能检测、优化与高可用上花费大力气,也产出了各种APM(application performance management应用性能管理)工具及HotFix(热修复)方案,没有用吗?

再试想下,如果应用在启动时期,因为第三方SDK初始化出错而导致连续崩溃,而HotFix无法生效。连续的启动崩溃体验极其糟糕,你说用户最终会卸载吗?

启动崩溃的诱因有:

  • 各种三方 SDK 初始化配置出错;
  • 各种文件包括但不限于数据库、XML 的拷贝或操作失败;
  • 各种网络请求下发了脏数据;
  • 各种资源包的下载、合并导致的脏数据,包括但不限于闪屏图、Zip 包、修复包等;
  • 用户由跨 N 多个版本的低版本 App 升级到最新版引发的脏数据。

大家不要觉得我在危言耸听,我举一个我们iOS实际的例子:有次某广告商大大服务端下发错误字段,导致应用读取解析失败,App启动奔溃,用户再也进不了应用。对我们的伤害是巨大的,对我们的教训是惨痛的。

随之而来的问题就是,谁来解决启动阶段的崩溃,怎么解决呢?

历经N个月的摸索,跨越众多版本,以及小渠道的实践,应用启动阶段的安全模式就应运而生了。

安全模式的设计

七猫安全模式致力于解决APP启动阶段的崩溃等问题,同时具备配置中心、自主修复、动态修复、数据中心、测试五个方面,是一整套启动保护的解决方案。

  1. 配置中心: SDK配置开关、新老功能可切换
  2. 自主修复:在APP连续Crash情况下具备分级、无感自修复能力:安全模式的一级修复策略,二级修复策略
  3. 动态修复:热修复能力、可监控、灰度、回滚、清除
  4. 数据中心:监控告警功能,让你及时发现问题;重点问题日志排查分析
  5. 快速测试:针对测试加入特殊处理(开发模拟连续崩溃工具,见下图),提高测试效率。优化预发环境下测试,优化每次回归验证安全模式的难度

策略方案

安全模式的策略方案分为三点,具体描述见以下条目:

1、捕获异常

1.1 异常分类:

检测连续闪退,可以通过捕获异常来实现,异常分几种:

  • RuntimeException --设置主线程的 UncaughtExceptionHandler 来捕获运行时的崩溃
  • ANR --无法捕获的
  • Native 信号异常–注册信号处理函数,捕捉 native crash

1.2 崩溃的捕获:

设置主线程的 UncaughtExceptionHandler 来捕获运行时的崩溃
在 Application 中执行相应保护策略:

private int crashNum;//崩溃次数
@Override
protected void attachBaseContext(Context base) {
    super.attachBaseContext(base);
    if(crashNum> 3){
        // 删除文件,恢复到重新安装的状态
    }
    if(crashNum> 5){
        // 清除热修信息
    }
}

1.3 优缺点

  • 可能会与项目中已有的第三方异常收集框架冲突,漏检测。
  • 可能会与项目中已有的异常处理耦合,代码逻辑混乱。
  • 最大问题是不够准确,缺少对 Native 的异常处理。

2、标记数

2.1 前言

天猫安全模式原理:APP crash 的原因有很多,每个 APP 设计的方案也有不同,将其所有的异常错误都捕捉到很困难,因此我们换了个方式,完全从用户的角度来思考什么是异常退出,也就是打标记 flag 方式。

2.2 思路

  • 进入应用的时候就记录一个崩溃次数,在满足一定条件之后则认为启动阶段没有异常,同时将崩溃次数重置回复初始状态。
  • 异常次数到达一定程度则进入安全模式。
  • 需要维护一个崩溃次数,进入应用就把崩溃次数 +1

2.3崩溃次数重置时机
满足一定条件则重置崩溃次数:

  • 完成二级修复策略
  • 用户正常启动应用满 10 秒
  • 用户正常退出应用
  • 用户主动从前台切换到后台

2.4分级修复策略

  • 一级修复策略:业务线行为;更新 SDK 网络配置;
  • 二级修复策略:清空整个 App 数据,重置至初始安装状态;清除热修复包或者别的资源包;
  • 阻塞修复策略:阻塞进程,优先执行预设任务,例如:请求以及运行热修复包,等待全部完成之后再执行正常流程;
  • 多次请求失败后禁止请求(给服务端减压)

2.5 优缺点:

  • 标记数逻辑简单,与已有代码耦合小。
  • 在启动阶段,用户从前台切换到后台时,用户是否强杀了 APP 又或者多久又切回来都不清楚,对 crashCount 值是否准确有影响。

3、页面生命周期内的异常捕获

3.1前言
很多时候由于一些微不足道的 bug 导致 app 崩溃很可惜,Android 默认的异常杀进程机制简单粗暴,但很多时候让 app 崩溃其实也并不能解决问题。

有些 bug 可能是系统 bug,对于这些难以预料的系统 bug 我们不好绕过。还有一些 bug 是我们自己编码造成的,对于有些 bug 来说直接忽略掉的话可能只是导致部分不重要的功能没法使用而已,又或者对用户来说完全没有影响,这种情况总比每次都崩溃要好很多。

3.2 简介
activity lifecycle exception catch:在执行 Activity 或 Service 生命周期发生异常时对该异常的捕获和处理方式,用来降低一些非必要的 crash。

3.3 小渠道探索与实践
在注册全局异常捕获时,控制在页面Activity生命周期内是否捕获Hook。

测试发现确实可以捕获在页面生命周期中的ActivityThread引发的异常,比如,我们模拟个RunTimeException的崩溃。小渠道验证的确也收集到一些崩溃,说明是起到捕获异常的作用。

捕获到异常后,只会将出错的页面关闭,而不会影响到App,再结合完善的监控系统、报警机制,终将带给用户极佳的体验。

思考

安全模式探索与实践的历程也经历坎坷、备受挫折,需要足够的延迟满足感。团队一直坚持不懈,完成每一次的挑战,为安全模式顺利上线做出了最大努力,且后续还会加油持续做的更好。

以下也带来我们的继续思考:

  1. 安全模式的解决场景是否可以复用到其他特定场景比如:阅读器连续崩溃,更或者就像微博:对连续崩溃后的用户友好交互界面。
  2. 这个系统真正的意义在哪里?快速响应线上问题、提高用户体验。贯彻七猫的企业文化:对用户好一点。

总结

到这里所有的都完成了。总结一下,安全模式就是APP启动阶段的保护实践。七猫安全模式就是致力于解决APP启动阶段的崩溃等问题,同时具备配置中心、自主修复、动态修复、数据中心、测试五个方面的一整套启动保护的解决方案。

欢迎加入我们!
目前团队 Android 与 iOS 岗位还有空缺,欢迎优秀的人才加入我们的团队,一起搞事情。
内推邮箱地址:yuminhua@qimao.com

Reference

  1. 安全模式:天猫 App 启动保护实践
  2. 关于应用启动连续崩溃的解决思考