Android 的用户界面渲染是从应用中 "生成" 一帧然后显示在屏幕上,为了确保用户能够获得顺畅的交互体验,您的应用需要根据设备的刷新率完成每一帧的 "生成"。例如,Pixel 6 设备支持每秒最多渲染 90 帧,这就意味着应用的每一帧任务都要在 1000/90 = 11ms 内完成,如果没有,Android 框架就会将这一帧的渲染跳过,用户就会从视觉上感受到界面运行缓慢,我们称这种情况为 "卡顿"。
出现卡顿的原因有很多种,例如,由应用导致的卡顿或由 SurfaceFlinger 导致的卡顿。本文重点关注由应用导致的卡顿,以及 Android Studio 提供的用于发现和消除这些卡顿的工具,方法是在应用交互的过程中检查记录的轨迹来解决应用的性能问题。
从实时交互记录轨迹
以下示例使用 GitHub 性能示例仓库中的 JankStatsSample 应用来展示如何使用 CPU 性能分析器锁定卡顿的原因:
3. 点击 Profiler 左侧窗格中的 + 图标启动新的性能分析会话,然后选择要运行性能分析器的设备名称和应用进程。
注意: 虽然可以分析 "可调试应用" (debuggable app),但推荐做法是分析 "可分析应用" (profileable app),因为分析 "可调试应用" 会导致性能开销显著增加。更多详细信息,请参阅关于可分析应用的文档:
https://developer.android.google.cn/studio/profile#profileable-apps
4. 点击 CPU 行。
5. 选择 System Trace Recording,点击 Record。
6. 与应用互动以收集数据,然后点击 Stop 按钮。Android Studio 将显示 Display 窗格,其中可见卡顿帧,也可以选中 All Frames 复选框,让轨迹记录也显示非卡顿帧。
将鼠标指针悬停在帧上或点击帧,即可查看详细的帧信息。如果选中 All Frames 复选框,将有三种类型的帧。
选中 Lifecycle 复选框,可以切换显示/隐藏四个附加轨迹。
四个轨迹:
Frames on display
Android Studio Bumblebee (2021.1.1) 稳定版中已经加入了这些轨迹信息的显示。您可以在文档中查看每个轨迹的详细说明:
https://developer.android.google.cn/studio/profile/jank-detection#jank-detection-android-11
检查卡顿帧
接下来,我们来找出卡顿帧出现的原因。
1. 在 Janky frames 轨迹中选择一个卡顿帧,Display 窗格将突出显示相应的生命周期数据,Threads 窗格将突出显示相应的线程数据。
虚线 Deadline 代表截止时间。当帧的时长超过该截止时间时,该帧即被视为卡顿。
您还可以在 Android Studio 的右侧窗格中查看详细分析。
2. 如果您看一下应用主线程相应的轨迹窗格,可以看到大量的时间花费在 "View#draw" 中。
此外,如详细分析窗格中的主线程状态所示,大量线程所处的状态是正在休眠。
3. 我们看一下调用 View#draw 的代码。View#onDraw 在 JankyView 类中被复写:
override fun onDraw(canvas: Canvas) {
simulateJank()
super.onDraw(canvas)
}
fun simulateJank(
jankProbability: Double = 0.3,
extremeJankProbability: Double = 0.02
) {
val probability = nextFloat()
if (probability > 1 - jankProbability) {
val delay = if (probability > 1 - extremeJankProbability) {
nextLong(500, 700)
} else {
nextLong(32, 82)
}
try {
// 在分析器中通过轨迹使卡顿更易被锁定
trace("Jank Simulation") {
Thread.sleep(delay)
}
} catch (e: Exception) {
}
}
}
如需了解关于读取轨迹和添加自定义轨迹的更多信息,请参阅系统轨迹概述:
https://developer.android.google.cn/topic/performance/tracing
4. 将代码更改为在 onDraw 中不去调用 simulateJank 方法,然后查看是否仍然存在卡顿帧。
override fun onDraw(canvas: Canvas) {
// simulateJank()
super.onDraw(canvas)
}
这一次,重新运行系统轨迹录制时,您会发现与应用的交互不再有卡顿帧啦。
加载保存的轨迹
3. 然后,导航到 + -> Load from file… 加载已保存的系统轨迹录制,选择上一步中导出的已保存文件。
4. 选择要分析的进程。显示进程列表下拉菜单后,输入进程名称的一部分即可快速查找。
然后,您可以加载保存的轨迹,像从实时互动录制一样查看卡顿帧。
总结
本期内容就到这里了,从 Android Studio Chipmunk 开始,您能够看到更精准的性能分析数据,更快锁定应用卡顿。
请查看文档进一步了解 CPU 性能分析器的用法,也欢迎您前往 Android Studio 中的 "Help -> Submit Feedback" 帮助我们改进工具。
△ Android 应用性能近期更新
我们新发布了一个库,可用于检测和报告在用户设备上运行的应用卡顿,如果您希望了解更加详细的内容,欢迎查看 JankStats 文档:
https://developer.android.google.cn/studio/profile/jankstats
点击屏末 | 阅读原文 | 进一步了解 CPU 性能分析器的用法