我正在参加「启航计划」
为了吸睛,我还真是无所不用其极,把能想到的标题都写上了,咱们见怪不怪吧…
先来点废话:
听说最近 Android 岗位变多了,你去面试了么?
面试官:你简历中说到了卡顿优化,做了哪些优化呢,打开说说。
你:哦,脑子飞速闪过网上的文章,然后说内存走漏、内存抖动、发动优化、布局优化、图片优化、网络优化…
面试官:细节呢,详细些。
你:哦,啊,哈哈哈…\
文章初衷:
网上优化文章许多,各种主题都有,每次看那些大牛文章都觉得好有道理,啊我会了,可实际运用到项目的时分又不知道从哪里下手…
咋的,说的是不是你?横竖这真的便是我。所以想着把自己做的一些小优化共享出来,主题尽量明确,看后更易上手,让国际更夸姣「为以后的面试润饰」…
先不引入 Matrix 等第三方库,本文宗旨:先从简略处下手,尽量主题明确
。
Android Profiler
子曰:“工欲善其事,必先利其器。居是邦也,事其大夫之贤者,友其士之仁者。”
假如你刚刚开端优化,那就别上来就扯 systrace 和 traceview「已被抛弃」 了,先看看 Android Profiler 吧。看看它能做什么:
- CPU 功能分析器有助于查出运行时功能问题。
- 内存分析器有助于跟踪内存分配状况。
- 网络功能分析器可监控网络流量运用状况。
- 能耗功能分析器可跟踪能耗状况,这有助于分析电池电量消耗过快的问题。
内存走漏
ps:假如熟练此段可略过。别的只涉及到 java 层,未涉及到 native 层走漏。
几年前,说到内存走漏,许多人都会想到 LeakCanary,上手简略,并且去面试的时分许多时分还会问 LeakCanary 完成原理 / 为什么不能在线上运用等等…
现在年代换了,官方直系血亲来了。
本文运用的Studio版本:Android Studio Giraffe | 2022.3.1 Beta 1
先说定位过程
-
创造走漏环境:
App 多点几个页面,杂乱页面可执行屡次进入/退出的操作,再回到App 主页; -
打开 Profiler 界面:
- 点击如下绿框选中icon
- 出现如下图,内存问题排查需求进入到 memory 模块
- 捕获堆转储「即挑选绿框内容」,并点击record,会主动开端分析,等候即可
- 主动停止后,会出现如下展示:
- 挑选绿框选项,会筛选出 activity/fragment 层级的内存走漏
卡顿「掉帧/ANR」
适用场景:已知某个行为会触发卡顿,eg:点击到某个tab,进入某个页面
先说定位过程
- 进入Profiler,点击进入 CPU 模块
- 选中第四个「Java/Kotlin Method Sample」,点击record
- 自己点击stop后,等候生成文件,有需求能够右键保存为 trace 文件;双击 main 模块,点击详细分析 UI 线程做了啥大事。
看到上图其实已经大约意识到工作没这么简略了…为啥?看颜色:
- 对体系 API 的调用显示为橙色;
- 对运用自有办法的调用显示为绿色;
- 对第三方 API(包括 Java 语言 API)的调用显示为蓝色
tip:调理下图绿框中的两个箭头方位也能够放大/缩小
接下来便是要点看绿色部分,看看自有办法为啥导致绿色长度这么明显。
处理的问题
下面列出来的,都是我经过上面的办法,处理的部分问题。
声明:以下数据均比出产环境的值要小…
1.PackageInfo 相关的问题
经过 CPU Profiler 能够看到下图
/**
* App 经过 PackageManager 去获取运用信息,是卡顿操作,若多个当地调用应存储为常量
*/
val packageInfo: PackageInfo? by lazy { PackageUtils.getPackageInformation(App.context) }
val applicationInfo: ApplicationInfo? by lazy { packageInfo?.applicationInfo }
val packageName by lazy { packageInfo?.packageName }
val packageVersionCode by lazy { packageInfo?.versionCode }
val packageVersionName by lazy { packageInfo?.versionName }
val firstInstallTime by lazy { packageInfo?.firstInstallTime ?: 0L }
val lastUpdateTime by lazy { packageInfo?.lastUpdateTime ?: -1L }
2.Websocket 运用问题
如下图,发现 UI 线程里边有许多GSON 解析的操作,再跟踪,发现 App 中关于WebSocket 的数据接收和处理,根本上是 UI 线程,形成掉帧 or 卡顿 or ANR。其实也羞愧,这个问题竟然之前没留意…
关于咱们的 App 来讲,更丧命,由于场景主要是歌房,消息根本都是经过 ws 来处理的,里边有各种UI的频繁更新、各种动效、各种动画、歌曲演唱…
所以凭仗这个优化了整个App 关于 ws 的运用,改完后经住了测试组的压测、发热/卡顿等都好了许多,详细办法思路在这里 Android功能优化实战 – 直播间场景
3.EmojiManager.renderEmoji 办法
4.图文混排
项目中应该都有这种形式,text+icon 这种,假如在 RecyclerView 中运用,那卡顿就比较明显了
5.骨架屏耗时
这是之前的事务需求,后来一跑太耗时,直接下掉了…
6.获取告诉是否可用
事务中许多关于是否获取告诉权限的判别,这种case 应该存为全局常量,必要状况再去从头获取值。
Profiler 部分小结
这里说的只是开端运用,还有更细节且更精准定位某个办法的办法,需求去持续探究了。不过虽是开端运用,但是在我公司的项目里处理了不少问题,咱们也开端吧 ~ 在一些场景下用 Profiler 去定位卡顿是不方便的,所以有许多优异的框架 Matrix、Booster、KOOM 等。
线程优化
这个主题很大,开端的话,时间也比较长,前期储藏较多常识点,详细运用还要结合自己的项目,我在这里只是提一下主题。
这个文章能够让你上手,并且认识到所需求的常识点:AOP 面向切面编程, 字节码插桩, 自定义 Gradle Plugin + Transform + ASM「小白操作版」
这个文章能够让你了解的多一些:AOP / 面向切面编程 / 字节码插桩 / ASM / 字节码扫盲学习 / 解读版
最后说点
- 上面关于 LeakCanary 的问题,不会的话去查一查吧,再深化的话会接触到 Matrix ,关于 Matrix 的记录我也写过,看这里Matrix-TraceCanary 实际运用
- 本文要点是在收拾,说到的东西不新,但是比较经典。
- 收拾这个过程挺好的,过程中会锻炼自己的总结概括能力,仔细审视自己提及到的常识点是否正确,所以你也开端吧。
-
常识体系
非常重要,零散承受常识点的话比较被迫,所以学习过程中就需求收拾自己的常识体系,这样面试的时分就能够从点到面打开了「我假定的」。 - 多看 Android 官方文档,看 Android 官方文档说到的项目,比方你想
体系学习
最近很火的 MVI/Compose。 - 身处旋涡,就再挣扎一下。
- 其实这些乱七八糟的写的不是我本意,但是逼着自己写一下。为什么我会这么费尽心思的想写点啥? 由于姐告诉我了,只要我好好写,就给我一个证书,然后我就想用那个证书发个朋友圈… 你会帮我点赞的对么?
参考链接
官方文档-分析运用功能
官方文档-检查运用的内存运用状况