Android 性能优化技术月报 | 2025 年 1 月
每个月都会有一些 Android 性能优化相关的优质内容发布,然而,碎片化阅读使得这些知识难以形成完整体系,且容易被遗忘。为解决这些问题,我决定尝试使用技术月报的形式,总结我在最近一个月内查阅的 Android 性能优化相关的优质内容。
月报的主要内容包括:整理展示我在最近一个月所查阅的 Android 性能优化领域的最新技术动态、精选博客,精选视频等内容。
精选博客
Android QUIC 实践 - 基于 OKHttp 扩展出 Cronet 拦截器
文章主要介绍了在 Android 中基于 OKHttp 扩展出 Cronet 拦截器以实现 QUIC 实践
- QUIC 概述:Google 开发的实验性传输层协议,基于 UDP,具备多路复用、减少延迟等特性,旨在取代 TCP。
- Cronet 引入:引入方式有 gradle 引用(版本有限)和从 Google Cloud 下载(版本新但不稳定)。
- 搭配 OKHttp 原因:为降低风险、减少成本,便于快速回退,许多项目深度依赖 OKHttp,可后续再考虑替换或融合。
- 实现方案 - Cronet 逻辑:自定义 Cronet 拦截器,实现请求转换、请求处理、响应转换和性能统计,涵盖多个功能类。
- 实现方案 - 嵌入操作:在 OKHttp 的 Builder 中添加 CronetInterceptor,完成 QUIC 协议栈接入。
- 后续工作:上线 QUIC 还需完善性能监控、报警、容灾机制,优化 Cronet 或替换网络库。
移动端弱网优化:携程APP移动网络优化实践(弱网识别篇)
对于网络质量识别,业内做的比较早的是Google的NQE(Network Quality Estimator),国内大多数网络质量识别方案也都参考了Google NQE,NQE中识别模型的输入主要是HttpRTT、TransportRTT、DownstreamThroughput这三个指标。
对于上述提到了三个输入指标,携程从如下网络行为中进行数据采集:
1)TransportRTT:通道心跳耗时、Tcp通道建联耗时、Http通道建联耗时( 2)HttpRTT:标准Http请求的responseHeader开始接收时间减去RequestHeader的开始发送时间、自定义网络通道请求的开始接收时间减去开始发送时间; 3)NetworkSuccessRate:Tcp建联成功状态、Quic建联成功状态、心跳成功状态、Http请求是否完整接收到Response。
获取到以上数据之后,先过滤无效数据,采用半衰期动态权重计算,RTT 用加权中值、成功率用加权平均计算,引入成功率趋势提升实时性。
最终携程90%准确率的模型对应的弱网阈值如下(不同业务场景的网络请求差别较大,仅供大家参考):
1)HttpRTT > 1220ms;这个值是线上HttpRTT的TP98值,与弱网占比相近; 2)TransportRTT > 520ms;同线上TP98值; 3)NetworkSuccessRate < 90%; 4)SuccessRateTrend < 0.2;之前的0.1导致模型的结果切换过于频繁,最终调整到了0.2。
AGP8.0 插件适配中 学到的一些知识点
文章主要分享 AGP8.0 插件适配过程中的知识与经验,内容如下:
- gradle 依赖:插件开发时,gradle-api 依赖稳定但 API 少,建议直接用 gradle 依赖。
- 任务相关:可查询任务实现;任务可无输入但必有输出,输入输出类型不对应,同时介绍了相关注解;任务状态有执行、未执行等多种。
- 文件集合差异:FileCollection 无文件树形结构,FileTree 保存了该结构。
- Artifacts API:AGP8.0 后旧任务插入机制失效,推荐用 Artifacts API 编排任务,如修改 manifest 文件,并介绍了相关 Artifact 类型。
- 字节码处理:AGP8.0 + 中,asm 字节码修改更简单,javaassist 稍复杂,分别给出示例。
- 遗留问题:AGP8.0 + 中 artifact 不支持 mergeResources 任务,无法在编译期压缩图片资源。
./gradlew help --task <taskName>
程序员焦虑症之「没用过」和「不知道」,码农的「拧螺丝」之道
- 你还在用 Eclipse ,现在都用 Android Studio 了
- 你还在本地 jar 包,现在都用 Gradle 远程依赖了
- xUtils 和 Afinal 听说过没?开发神器啊
- 你怎么还在用 ImageLoader ,知道 Picasso 吗? 用过 Fresco 没有?现在都推荐 Glide 了
- 你知道 GreenDao 吗?现在谷歌都推荐 Room 了,你用过 Realm 吗?
- 你还在用 ButterKnife?现在都用 DataBinding、ViewBinding 了
- 你怎么还用 Apache HttpClient,试试 Volley 呗?
- 现在都是 OKhttp 了,那你知道 Retrofit 吗?
- 你用过 gPRC 和 GraphQL 吗?
- 你还在用 MVC ,你知道 MVP 吗?我都用 MVVM、MVI 了
- 你用过 dynamic-load-apk、VirtualAPK、DroidPlugin、RePlugin、tinker 吗?
- 你知道 Dagger 吗?现在都 Dagger2 了
- 你还在用 Dagger ? 现在已经是 Hilt 了
- 你用过 EventBus 吗?
- 你知道 LeakCanary 吗?听过 BlockCanary 吗?
- 你还在用 Java 的 Dagger 啊,Kotlin 都用 Koin 了
- 你知道 Rxjava 吗?已经 Rxjava2 了
- 你用过 Couroutines 和 Flow 吗?
- 你知道 LiveData 吗?
- 用过 jadx 和 apktool 吗?
- 怎么还在用 Java ?Kotlin 都烂大街了
- 你知道 Jetpack 吗?用过 Lifecycle、Navigation、CameraX、Paging、Glance、Slice、Startup、Viewpager2、DateStore、WorkManager 吗?
- 你做过小程序吗?uni-app 听过吗?React Native 知道吗?Flutter 、KMP、Compose 了解不?
- 鸿蒙 Next 你适配了没?ArkTS 和 ArkUI 学了没?
- ····
我们的工作就是使用别人「制作好的工具」,所以我们热衷追逐「新工具」,但是,大多数时候,我们又不了解工具是如何工作的,我们只是一直在“反复”的学会如何使用它们,并且焦虑于,我们还没全都学会。
「追新」带来的「错觉」是,牛逼的是扳手的制造者,而作为使用者,我们都是踩着别人的肩膀混口饭吃的工人。就像开车,开「自动档」并没有比「手动挡」厉害多少,但是我们的目的也不是为了认识所有汽车档,我们的目的只是为了开车,然后进一步能力就是修车和调教。
在不理解运作的原理,没有基础知识铺垫,当任务变成修理一个发动机时,当任务变成提高框架的性能瓶颈时,就会无从下手。