likes
comments
collection
share

啊?还不会卡顿优化?面试官:说下简历中提到的优化/整理下早期自己做的优化

作者站长头像
站长
· 阅读数 53

先来点废话: 听说最近 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。其实也惭愧,这个问题竟然之前没注意...

啊?还不会卡顿优化?面试官:说下简历中提到的优化/整理下早期自己做的优化

3.EmojiManager.renderEmoji 方法

啊?还不会卡顿优化?面试官:说下简历中提到的优化/整理下早期自己做的优化

4.图文混排

项目中应该都有这种形式,text+icon 这种,如果在 RecyclerView 中使用,那卡顿就比较明显了

啊?还不会卡顿优化?面试官:说下简历中提到的优化/整理下早期自己做的优化

5.骨架屏耗时

这是之前的业务需求,后来一跑太耗时,直接下掉了...

啊?还不会卡顿优化?面试官:说下简历中提到的优化/整理下早期自己做的优化

6.获取通知是否可用

业务中很多关于是否获取通知权限的判断,这种case 应该存为全局常量,必要情况再去重新获取值。

啊?还不会卡顿优化?面试官:说下简历中提到的优化/整理下早期自己做的优化

Profiler 部分小结

这里说的只是初步使用,还有更细节且更精准定位某个方法的方式,需要去继续探索了。不过虽是初步使用,但是在我公司的项目里解决了不少问题,大家也开始吧 ~ 在一些场景下用 Profiler 去定位卡顿是不方便的,所以有很多优秀的框架 Matrix、Booster、KOOM 等。

线程优化

最后说点

参考链接

官方文档-分析应用性能 官方文档-查看应用的内存使用情况

转载自:https://juejin.cn/post/7248183510234497084
评论
请登录