共计 1870 个字符,预计需要花费 5 分钟才能阅读完成。
核心概念解析
在深入流程之前,我们需要明确几个关键组件的定义和关系:

- Activity:用户交互的入口单元,负责管理生命周期和界面内容
- Window:每个 Activity 包含一个 PhoneWindow 实例,是视图的容器
- Surface:图形缓冲区的抽象,对应一块实际的内存区域
- SurfaceFlinger:系统服务,负责将所有 Surface 按 Z -order 合成最终帧
这些组件的关系可以表示为:Activity -> Window -> ViewRootImpl -> Surface -> SurfaceFlinger
完整流程分析
1. Activity 启动阶段
- AMS 交互:ActivityManagerService 创建 ActivityRecord
- Window 创建 :通过
attach()方法初始化 PhoneWindow - ContentView 建立 :
setContentView()触发 DecorView 创建
关键代码片段:
// ActivityThread.handleLaunchActivity
final Activity a = performLaunchActivity(r, customIntent);
if (a != null) {a.attach(context, window); // 创建 PhoneWindow
setContentView(layoutResID); // 加载布局
}
2. 视图测量与布局
当 ViewRootImpl 执行 performTraversals() 时:
- Measure 阶段:计算视图大小
- Layout 阶段:确定视图位置
- Draw 阶段:生成绘制指令
这个过程受 VSync 信号驱动,默认 60Hz 的刷新率意味着每 16ms 必须完成一次完整流程。
3. Surface 创建与绑定
通过 SurfaceControl 创建 Surface 的过程:
WindowManagerService分配窗口层级SurfaceControl创建本地 Surface- 通过
Surface.lockCanvas()获取 Canvas 进行绘制
// Surface.cpp 简化流程
sp<SurfaceControl> surfaceControl = new SurfaceControl();
surfaceControl->createSurface();
sp<Surface> surface = surfaceControl->getSurface();
Canvas* canvas = surface->lockCanvas(NULL);
// 执行绘制...
surface->unlockCanvasAndPost(canvas);
4. 合成阶段
SurfaceFlinger 的工作流程:
- 收集所有有效的 Layer
- 计算可见区域和 Z -order
- 使用 GPU 或硬件合成器 (如 HWC) 进行合成
- 输出到显示设备
性能优化要点
常见卡顿原因
- 主线程阻塞(超过 16ms 的耗时操作)
- 过度绘制(无效区域重绘)
- 图层过多(合成开销大)
- 内存抖动(频繁 GC)
- 不合理的动画参数
优化策略
- 减少布局层级:使用 ConstraintLayout 替代多层嵌套
- 启用硬件加速:在 Manifest 中配置
android:hardwareAccelerated="true" - 合理使用缓存:
View.setLayerType(LAYER_TYPE_HARDWARE, null) - 监控帧率:通过 adb 命令
adb shell dumpsys gfxinfo - 使用 Systrace 分析:定位具体耗时环节
避坑指南
- 避免在 draw()中创建对象:会导致内存抖动
- 谨慎使用 alpha 通道:会禁用硬件优化
- 注意 ViewVisibility 状态:GONE 比 INVISIBLE 更高效
- 限制 RecyclerView 滚动速度:快速滚动易引发卡顿
- 慎用 ClipPath:某些机型上性能极差
实践建议
推荐尝试以下验证方法:
- 使用
Choreographer.getInstance().postFrameCallback()监测帧耗时 - 通过
getWindow().setBackgroundDrawable(null)减少过度绘制 - 用
Trace.beginSection()标记关键代码段
思考题
- 如何验证某个 Activity 的完整渲染流程是否符合 16ms 标准?
- 当发现合成阶段耗时过高时,应该检查哪些指标?
- 为什么说 Surface 是 ” 双缓冲 ” 的实现基础?
总结
理解从 Activity 到 SurfaceFlinger 的完整流程,是优化 UI 性能的基础。建议结合 Systrace 工具实际观察 VSync 信号、主线程工作和合成器状态的三者关系,在实践中深化对渲染管线的理解。
正文完
发表至: 移动开发
近两天内
