屏幕1秒60帧,平均每帧16.6毫秒,如果代码实现不佳,或者过于复杂,导致一帧绘制时间大于16.6毫秒,则无法完成绘制,造成丢帧,连续出现掉帧,在现象上表现为卡顿。
adb shell am start -W com.zhoupushuju.zhouyi/com.rnmobx.MainActivity
结果
Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.zhoupushuju.zhouyi/com.rnmobx.MainActivity }
Status: ok
LaunchState: COLD
Activity: com.zhoupushuju.zhouyi/com.rnmobx.MainActivity
TotalTime: 931
WaitTime: 934
Complete
adb logcat -b all | grep am_activity_launch_time
结果
[0,78748358,com.zhoupushuju.zhouyi/com.rnmobx.MainActivity,931]
对于搭载 Android 12(API 级别 31)或更高版本的设备,CPU 性能分析器中 Display 窗格下的 Janky Frameworks 轨道中会显示捕获的轨迹。
如需检测卡顿情况,请按以下步骤操作:
image.png 如果 Select Deployment Target 对话框显示提示,请选择要将您的应用部署到哪个设备以进行性能分析。如果您已通过 USB 连接设备但系统未列出该设备,请确保您已启用 USB 调试。
image.png
image.png
image.png
对于搭载 Android 11(API 级别 30)的设备,CPU 性能分析器的 Frame Lifecycle 部分会显示捕获的轨迹。
image.png
Frame Lifecycle 部分包含层名称和四个轨迹。每个轨迹分别代表帧呈现流水线中的一个阶段。Frame Lifecycle 元素如下:
RenderThread
中的轨迹事件。Frame Lifecycle 部分说明了帧缓冲区在呈现流水线的不同阶段之间的切换方式。帧按帧号进行颜色编码,以便更轻松地跟踪特定帧。
Android Studio 还会在 All Frames 标签页中以表格格式显示轨迹中的所有帧。
image.png
Frame #、Application、Wait for GPU 和 Composition 列表示的数据与上方 Frame Lifecycle 部分的轨迹表示的数据一样。Frame Duration 列表示从 Application 开始到 Frames on Display 开始所经历的时间。这本质上是端到端呈现帧的时长。
您可以按任意列对“Frames”表进行排序,以便快速找到最短或最长的帧。该表还支持分页控件,您可以借助这些控件浏览数以百计的帧。
如需在 Android 11 上检测和调查卡顿情况,请按以下步骤操作:
image.png
image.png
image.png
对于搭载 Android 10(API 级别 29)及更低版本的设备,相关的操作系统图形管道信息会显示在 CPU 性能分析器系统轨迹中的单个部分,称为 Display。
image.png
RenderThread
轨迹事件。时长超过 16 毫秒的事件会以红色表示,以突出显示潜在的卡顿帧,因为它们超出了以 60 帧/秒 (fps) 的速度进行呈现的截止时间。0
、1
或 2
)。BufferQueue 可帮助您了解图像缓冲区在 Android 图形组件之间切换时的状态。例如,值 2
表示应用当前处于三重缓冲状态,这会导致额外的输入延迟。Display 部分会提供有助于检测潜在卡顿的实用信号,例如何时界面线程或 RenderThread
的用时超过 16 毫秒。若要调查导致卡顿的确切细节,您可以查看 Threads 部分,其中会显示与界面呈现有关的线程。
image.png
在上图中,Threads 部分显示了界面线程 (java.com.google.samples.apps.iosched
)、RenderThread
和 GPU completion
线程。这些线程与界面呈现有关,可能是导致卡顿的原因。
如需在 Android 10 或更低版本上检测卡顿情况,请执行以下操作:
image.png
W
,或在按住 <kbd style="box-sizing: inherit;">Control</kbd> 键(在 macOS 设备上,则按住 <kbd style="box-sizing: inherit;">Command</kbd> 键)的同时滚动鼠标滚轮,以便进行放大。继续放大,直到您看到界面线程和 RenderThread
中的轨迹事件。
image.png
在上图中,Choreographer#doFrame
显示了界面线程何时调用 Choreographer
来协调动画、视图布局、图像绘制和相关进程。DrawFrames
显示了 RenderThread
何时形成并向 GPU 发出实际绘制命令。
inflate
,这意味着应用正在花时间膨胀布局。当您放大其中一个 inflate
事件时,可以确切了解每个界面组件花费的时间,如下所示。image.png