本文为现代化 Android
开发系列文章第七篇。
完整目录为:
- 现代化 Android 开发:基础架构
- 现代化 Android 开发:数据类
- 现代化 Android 开发:逻辑层
- 现代化 Android 开发:组件化与模块化的抉择
- 现代化 Android 开发:多 Activity 多 Page 的 UI 架构
- 现代化 Android 开发:Jetpack Compose 最佳实践
- 现代化 Android 开发:性能监控(本文)
性能优化是开发永远绕不过的话题,也是通往高手的必经之路。但性能优化的前提是搭建了完善的性能监控体系,大公司都会投入人力建设完善的 APM
监控体系,而小公司则更多的只能使用大公司提供的平台与 SDK,甚至由于业务压力,往往也没有时间去搞什么性能优化。所以说这方面的成长,那得倒退几年,在大公司才有机会得到锻炼。而现在,该有的 APM
系统都有了,已经是维护为主了。对外的 SDK
与平台都在想方设法收点费了,小公司能够看数据分析的地方就更少了。
如果是学习的话,那么极客时间上张绍文大佬的《Android开发高手课》就是非常推荐的学习资源了,崩溃、内存、IO、存储、网络、启动、包体积、UI等方方面面都有讲得很深。而且大佬是非常注重线上监控的,力求做到问题早暴露、早处理。
作为业务开发的我,当然不是讨论各个底层的实现,而是利用各种库和工具来完成自己的监控目的,所以本文主要讨论的业务层可以使用哪些工具。
上报
各大平台提供大而全的 SDK
,则是采集-上报-分析一条龙的都承包了,对于使用端而言则是几句代码的事了,所以它点费也是理所应当,不过,小公司,非必要,给钱是不可能给钱的了。所以我在 emo
中开发了通用的上报库 report
,封装了立即上报、批次上报等行为逻辑,后端可以使用 Prometheus
,这就是把监控也作为业务数据上报的一部分。而因为 report
是一个通用的上报库,使用者需要自定义数据协议,所以 emo
之前规划的一个发展就是定制各种监控的数据协议,和后端提供配套的 docker
,不过也只是有心而无力,没这个排期。
Crash
Crash
、ANR
、OOM
应该是最受关注的监控对象,java
层的 crash
好捕捉,难的是 native
层的异常,难以捕捉,而且可能捕捉不到,所以往往为了获取详细的 crash
信息,大家都可能会同时接入几个 SDK
去监控。目前比较通用的可能还是 Bugly
,毕竟免费。但 Android
端 SDK
目前做得最好的可能是爱奇艺开源的 xCrash
,如果想要学习的话,阅读它的源码,应该是一个非常好的手段。
Bugly
额外添加日志文件支持得不是很好,可是很多 crash
,我们往往要去日志中去寻求异常原因。所以目前我自己的异常上报方案就是使用 xCrash
,在 crash
时把日志也上报一份。
除此之外,官方也在 Android 11
提供了 App Exit Reasons
这个 API
, 用于我们获取用户是因为什么情况退出应用的,目前,应该主流的手机都升级到 11
以上了吧,所以它也可以用起来了,而且它的 reason
还包括 REASON_LOW_MEMORY
、REASON_EXCESSIVE_RESOURCE_USAGE
等众多原因,作为数据分析,也是非常有用的。
内存泄漏
内存泄漏目前的主流分析工具就是 LeakCanary
了,所以 App
怎么也得接入下,这个也是面试官非常喜欢问的问题了,属于面试必备了,了解下其实现原理也是很有必要的。
网络监控
网络监控主要是两个点,一个是上下行流量的监控,防止开发写了有问题的代码,出现在循环内疯狂请求后台的情况,除了会给后台压力,也容易被用户投诉。emo
的 network
做了一个简易的上下行流量的采样,可以一段时间采样一次,看是否出现突发流量的情况。
另一个就是网络连接稳定、耗时的监控了,由于目前基本上都是 OKHttp
了,所以直接使用它提供的 EventListener
就足够用了,就可以把 ssl
握手时间、dns
时间、connect
时间等都统计下来。网络请求一般是非常多的,一般客户端需要先聚合下再上报给后台。
卡顿监控
卡顿监控,以前基本上就是以下两种方案:
Choreographer
回调Looper
自定义Printer
我们可以使用微信的 Matrix
来监控卡顿,其实现方案是基于 Looper
来做的。
后面系统提供了 FrameMetrics
接口,然后 jetpcak
开发了库 Metrics
,jetpack
的实现保证了良好的兼容性,可惜目前稳定版还没到来,估计以后它就是主流了。
启动监控
启动优化也是一个重要的话题,如果首次启动时间久了,用户可能就放弃使用了。Google Play
可以采用大杀器 Baseline Profile
来优化应用首次安装后的启动时间。而国内的厂商到目前都没有追随一下的意思,所以启动耗时就依赖于业务层的改进,把能晚点初始化的东西就晚点初始化。
微信的 Matrix
也提供了启动耗时的监控,用就行了。
系统也提供了 reportfullydrawn
方法,可以由业务方来告诉系统我的数据加载完成了,从而可以报告启动到真正界面可用的时间。不过这个是为了官方提供的分析工具用的,不能直接用于线上监控。
最后
Matrix
除了上面提到的这些,还包括了:慢方法检测、APK 分析、 SQLite 检查、电脑优化、内存重复图片检测、IO 检测等等。如果是国外市场,那就可以使用官方的各种诸如 Firebase Crashlytics
服务了。
如果是真的想学习这些技术,那就去看 xCrash
、LeakCanary
、Matrix
源码,一切的知识尽含其中。但需要巨额的时间投入。不过已经被工作压迫得喘不过气,又哪来的闲余时间呢?大伙都在业务上卷得你死我活的,这种性能优化总会被无限期延迟,也就永远没有实践的机会。
总是背负着无尽的技术债,跪倒在一次又一次的需求变更前,过着大负大跪的程序员生活,偶尔翻看下被丢掉的计算机基础知识,以求温故知薪。
目前这个系列文章就写到这里了,之后会继续更新一些技巧与细节的讨论与思考,诸如 Compose
跨页面通信、Text
行高变更等知识。