共计 1222 个字符,预计需要花费 4 分钟才能阅读完成。
从 Perfetto 曲线看 GPU 性能问题
最近用 Perfetto 抓取了我们应用的 GPU 渲染数据,发现了一个典型问题:部分帧的渲染时间超过了 16ms(60FPS 标准),导致明显的卡顿。曲线图上能看到明显的波峰,这些就是需要优化的重点帧。

Android 图形系统架构解析
- SurfaceFlinger:Android 的图形合成器,负责将各个应用的 Surface 合成为最终显示的画面
- VSync 机制 :垂直同步信号,控制画面刷新的节奏,避免画面撕裂
- Choreographer:协调应用渲染与 VSync 信号的组件,确保 UI 更新与屏幕刷新同步
这三个组件协同工作,构成了 Android 图形渲染的基础架构。理解它们的交互机制,是进行 GPU 优化的第一步。
不同渲染路径对比
- Software 渲染 :
- 优点:兼容性好
-
缺点:性能差,CPU 负担重
-
Hardware 渲染 :
- 优点:性能好,利用 GPU 加速
-
缺点:某些复杂效果可能不支持
-
Canvas 渲染 :
- 优点:灵活度高
- 缺点:需要手动优化
优化措施代码示例
使用 ViewStub 延迟加载
<ViewStub
android:id="@+id/stub_import"
android:inflatedId="@+id/panel_import"
android:layout="@layout/progress_overlay"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
优化 RecyclerView 的 onBindViewHolder
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
// 避免在这里进行耗时操作
val item = getItem(position)
holder.bind(item) // 提前处理好的数据直接绑定
}
正确设置 layerType 属性
view.setLayerType(View.LAYER_TYPE_HARDWARE, null);
// 对于动画视图特别有效
避坑指南
-
避免在 draw() 中创建对象 :
draw() 方法会被频繁调用,在这里创建对象会导致大量 GC -
TextureView vs SurfaceView:
- SurfaceView:性能更好,但有层级限制
-
TextureView:更灵活,但性能稍差
-
RenderScript 使用建议 :
- 仅在处理复杂计算时使用
- 注意及时释放资源
GLSurfaceView.EGLConfigChooser 的作用
这个接口用于选择 EGL 配置,影响 OpenGL ES 的渲染质量。通过自定义实现,可以优化渲染效果和性能。
实战建议
建议读者使用以下 ADB 命令抓取 GPU 数据:
adb shell dumpsys gfxinfo <package_name>
然后对比优化前后的数据,重点关注:
– 平均帧时间
– 超过 16ms 的帧比例
– 最大帧时间
通过这样的量化分析,可以明确看到优化效果。
正文完
