FrameMetricsListener
FrameMetricsListener 是 Android 7.0(API 级别 24)引入的一种性能监控工具,用于监听和分析每一帧的渲染性能数据,帮助开发者进行 UI 性能调优,尤其是在定位掉帧、卡顿问题时非常有用。
一、基本概念
FrameMetricsListener 是通过 Window 类的 addOnFrameMetricsAvailableListener() 方法注册的回调接口。
每一帧渲染完成后,系统会将该帧的相关性能数据以 FrameMetrics 对象的形式传递给你,从而可以分析:
测量(Measure)耗时
布局(Layout)耗时
绘制(Draw)耗时
同步(Sync)耗时
呈现时间(Frame Time)
GPU 呈现时间(可在支持的设备上获取)
等等…
二、注册方式
1 | window.addOnFrameMetricsAvailableListener( |
你还可以在合适时机取消监听:
1 | window.removeOnFrameMetricsAvailableListener(listener) |
三、支持的 Metrics 类型
FrameMetrics 提供了多个常量,用于获取不同阶段的耗时(单位是纳秒 ns):
常量名 说明
FrameMetrics.TOTAL_DURATION 总耗时(从输入事件到帧提交)
FrameMetrics.DRAW_DURATION draw() 阶段耗时
FrameMetrics.LAYOUT_MEASURE_DURATION measure() + layout() 耗时
FrameMetrics.INPUT_HANDLING_DURATION 处理输入事件耗时
FrameMetrics.ANIMATION_DURATION 动画计算耗时
FrameMetrics.COMMAND_ISSUE_DURATION 发起 GPU 命令耗时
FrameMetrics.SYNC_DURATION 等待 GPU vsync 信号耗时
FrameMetrics.UNKNOWN_DELAY_DURATION 未知原因延迟的时间
FrameMetrics.FIRST_DRAW_FRAME 是否是首帧
四、使用场景
- 探测卡顿帧
1 | val total = frameMetrics.getMetric(FrameMetrics.TOTAL_DURATION) |
- 定位是哪一阶段耗时过长
通过对比 DRAW_DURATION、LAYOUT_MEASURE_DURATION、COMMAND_ISSUE_DURATION 等,可以定位是:
布局层级太复杂?
动画计算过重?
GPU 命令堵塞?
五、注意事项
仅支持 Android 7.0+(API 24)
FrameMetrics 默认只支持当前 Activity 的 Window,不包括 Dialog、PopupWindow 等。
对性能有一定开销,不建议在发布版本开启。
可结合 Choreographer 使用,更准确标定一帧的 vsync 节点。
六、实践建议
对卡顿页面开启监听,收集一段时间帧数据后统计瓶颈所在阶段。
可以将耗时写入文件或上传服务器进行后处理分析。
结合 Trace 标签,进一步细化性能分析粒度。