Skip to content
阅读进度

状态已变化,但画面冻结,怎样继续追? ​

返回 工程项目复盘 目录

标准回答 ​

如果手势和业务状态都在继续,但画面停在旧内容,我会把问题转到帧的生产与展示链路。应用逻辑正常,并不能证明用户看到了新画面。

我先确认目标窗口和 displayId,避免分析了另一个屏幕或过渡图层。然后看 View 是否请求并完成更新、RenderThread 是否继续工作、目标 Surface 是否有新内容,以及 SurfaceFlinger 最终展示的是不是这个窗口。主线程空闲和 doFrame 有执行,都不足以说明后面的渲染和展示已经完成。

跨屏场景里,还会检查渲染目标是否已经交接、旧 Surface 引用是否仍被使用、尺寸与裁剪是否更新,以及快照层是否遮住了真实窗口。例如业务不断刷新,但输出仍指向旧目标,用户看到的就可能一直是新屏上的静态内容。这只是候选原因,需要用对应图层和帧的证据确认。

如果证据落在窗口交接,就修复目标更新、状态时序和资源清理;如果落在 GPU、缓冲区等待或合成侧,则携带同一时间线和帧信息联合定位。最后不仅看画面恢复,还要验证连续移屏、取消、返回和显示销毁,确保修复没有留下旧资源或新竞态。

关键机制 ​

  • 从目标窗口、displayId、图层和帧标识入手,对齐应用帧与展示时刻,避免看错屏幕或动画图层。
  • 检查 Surface 生命周期、旧 Surface 引用、裁剪/尺寸、可见性和过渡快照是否仍覆盖真实内容;是否存在资源等待需要 Trace 佐证。
  • 若证据指向切屏后的旧渲染目标或旧回调,修复方向是正确交接目标与会话;若是 GPU、合成或驱动问题,则携证据联合定位。

通俗例子 ​

假设业务持续刷新到旧 Surface,新显示仍覆盖着静态快照,看起来像整页冻住。应验证输出目标和图层关系,而不是仅缩短主线程任务。

追问与回答 ​

doFrame 正常为什么仍然会冻屏? ​

doFrame 说明应用侧某些帧调度工作在推进,但之后还有渲染、缓冲区提交、合成和展示。应用也可能每次都画出相同内容,或者把新内容提交到错误目标。因此我会把“有帧回调”“产生新内容”“新内容被展示”分成三个观测点,逐步确认它们是否属于同一个目标窗口和同一段操作。

怎样证明修复有效? ​

我会同时验证业务状态和实际画面推进,而不是只看日志恢复。相同场景下,输入后的状态变化、目标产帧和最终展示应该能对应起来。再覆盖重复移屏、动画取消、返回、前后台切换和显示销毁,确认没有旧回调或快照残留。对于低概率问题,还需要固定触发方式多轮复测,并记录验证范围,不能把一次成功当成根因已经消除。

易混淆点 ​

快照遮挡、旧 Surface 与 GPU 等待只是候选原因,不是本项目已经确认的根因。

参考资料 ​

内容来源 ​

用完整回答理解机制,用真实证据解释项目。