注册

Android稳定性方案浅析

定义: 这里的Android稳定性单指Crash


指标口径: 用户可感知崩溃率,以用户为纬度,即Crash设备数 / 总设备数


精细化单个bug的纬度:



  • bug频次
  • 爆炸半径
  • 影响时长

从崩溃的发生解决整个链路出发: RD编码 --> 线下测试 --> 灰度发版 --> 崩溃发生&数据采集聚类 --> RD修复 --> 版本发布


整体思路


image.png


1、编码阶段


制定代码规范,加强代码Review,引入静态代码检查,完善测试流程等减少问题发生


a、静态代码检查

有时会出现某些低级错误如:divide by zero 导致的crash,使用Lintdetekt进行静态代码检查不失为一种好方案,可以放在代码合入的SA阶段


b、查看是否需要解决警告问题

在我们编码或者改动历史遗留的代码时,AS中存在一些警告⚠️,commit时要根据提示进行review,是否需要每次修复和改动还有待商榷


c、检测SQL质量

参考Matrix SQLite Lint: 按官方最佳实践自动化检测 SQLite 语句的使用质量;(看能否拓展到其他场景)


d、依赖库的检查 (可以跟组件化相关)

采用gradle脚本编译时检查依赖库是否相同,解决不同组件或者不同APP之间SDK版本不一致可能导致的崩溃,避免CI阶段打包失败或者上线后出现异常



  • 新增or改动SDK检测,CI diff 产出依赖树 全功能提测阶段

e、review规范


  • 提交reviewer的质量把控意识;关键代码需要两个人review,+1 +2通过才可以合入
  • 跟流水线CI自动识别核心类文件要求两人review的能力结合起来

2、测试&流水线


提高稳定性的意识,不管多微小的改动都要进行自测!!!


a.单元测试


  • 重点模块的单测能力

b.自动化测试


  • 结合QA补齐自动化测试的能力,覆盖核心场景
  • 跟devops平台能力结合,将LeakCanary等能力跟Monkey结合,自动创建卡片
  • 针对函数接口的异常数据排雷测试(参考juejin.cn/post/702812…)

c.CI/CD


  • 流水线打包效率提升

3、崩溃数据采集&分析


正如RD讲的那样,给我一个崩溃堆栈我就能定位到问题所在,能完整的还原"事故现场"成为重中之重


a.堆栈反混淆

结合各个公司APM平台上传mapping文件以及符号表,每个崩溃数据均展示混淆之前的定位


b.平台堆栈聚类


  • 接入iqiyi开源的XCrash库或者breakpad,上报java和native的崩溃堆栈到Server并聚类展示
  • 接入开源的Sentry库并搭建本地私有化服务,实现崩溃的上报和聚类

c.平台数据状态标识

已修复、Pending、下个版本修复等状态或者备注的标识,每次分析结果留下文字记录


d.分模块上传关键数据

会员模块上传会员信息、支付模块上传订单信息等


4、灰度阶段


a.测试轨道前置小版本提前暴露问题

b.三方SDK降级策略

firebase、广告库等三方SDK升级一定要观察崩溃率变化,并做好降级处理


c.crash率异常熔断机制


  • 灰度过程缺少中间对Crash率异常的评定标准,业务异常的评定标准
  • 整体&每个崩溃数据的量级(该崩溃人数/安装率)记录,设定阈值,每日将两个版本对比骤增或者骤降的数据输出并产出报告

c.上车策略

核心思路是代码改动最小化,预留todo下迭代改,避免造成新的线上crash


5、重点问题解决


I.源码分析

虽然 androidxref.comcs.android.com 都可以在线查阅源码,但这两处的Android版本并不全;android.googlesource.com 这里可以下载到几乎所有版本的源码,本地通过 Sublime 分析源码也十分方便(可以直接显示和跳转到方法的定义&引用位置)。


II.OOM问题

a.大图监控治理


  • 线下监控:通过插件在 mergeResources 任务后,遍历图片资源,搜集超过阈值的图片资源,输出列表
  • 参考NativeBitmap 把应用内存使用的大头(即 Bitmap 的像素占用的内存)转移到 Native 堆;但是可能会导致32位虚拟内存不足
  • 在接口层中将所有被创建出来的 Bitmap 加入一个 WeakHashMap,同时记录创建 Bitmap 的时间、堆栈等信息,然后在适当的时候查看这个 WeakHashMap 看看哪些 Bitmap 仍然存活来判断是否出现 Bitmap 滥用或泄漏。 微信 Android 终端内存优化实践

b.hook pthred

采用bhook,针对pthread_create创建的子线程中发生了信号(SIGSEGV)进行兜底操作;相当于catch native crash,发生crash时重新执行之前的逻辑


c.32位虚拟内存优化


  • Patrons 通过一系列技术手段实现运行期间动态调整Region Space预分配的地址空间
  • mSponge 优化了虚拟机对 LargeObjectSpace 的内存管理策略,间接增加其它内存空间使用上限 (未开源)
  • pthread hook 对 native 线程的默认栈大小进行减半

image.png


d.监控

接入KOOM,进行线下OOM发生时的采样上报


III.native crash


6、防裂化&基础建设


a.版本回顾

崩溃数据自动化采集,以月度或者季度为纬度爬取数据,形成总结


b.崩溃保护和安全模式机制


  • 通过ASM在编译时对四大组件生命周期等关键代码加上try-catch处理
  • 通过一定的策略,针对反复重启导致的崩溃问题,让用户选择继续初始化或者清除数据

c.日志回捞


  • 全埋点用户操作路径辅助分析
  • 参考Logan进行日志回捞系统的建设,方便针对某一用户发生问题后捞回日志分析

d.移动端性能中台

自建集崩溃监控、上报、分析、归因于一体(可以参考Matrix直接建立),可以轻松定位各种线上疑难杂症,更有超详细性能、卡顿、打点等全流程监控处理平台


作者:陈泡泡_
链接:https://juejin.cn/post/7240037613793361976
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

0 个评论

要回复文章请先登录注册