外观
跨屏后短暂黑屏,应该怀疑哪些交接点?
标准回答
跨屏后短暂黑屏,我会优先确认用户看到的黑色来自哪一层:启动背景、应用窗口、空白显示区域,还是过渡图层。先认清对象,才能判断是没有内容,还是有内容但被遮住了。
接着把新旧内容的交接放在同一时间线上看。旧窗口或快照什么时候退出,新窗口是否已经建立、可见并具备可展示内容,它们的显示目标、层级、alpha 和裁剪是否正确。一个常见假设是旧内容先撤掉,新内容还没有准备好,中间出现空档;但不能因此忽略错误 Surface、背景或受保护内容等其他原因。
如果证据确实指向交接空档,我会让旧内容退出与目标内容就绪协调起来,使用平台适用的同步或事务机制,而不是随便加一个固定延迟。Activity 已经 onResume,或者某次 draw 返回,都不一定代表用户已经看到目标帧。
同时必须设计失败和取消路径。目标一直没就绪,不能让旧快照永久覆盖;用户中途取消,也要正确清理资源。验证时会覆盖正常交接、高负载、快速重复和中途取消,确认既没有空档,也没有新的旧画面残留。
关键机制
- 区分启动背景、应用窗口与过渡图层,核对它们的显示目标、可见性、alpha、裁剪和层级。
- 若确认是交接问题,就围绕实际内容就绪信号设计切换,并结合相应同步或事务机制;具体方式由平台能力决定。
- 就绪信号也要有超时、取消和失败恢复,避免为了不黑屏让旧画面永久遮住新内容。
通俗例子
假设旧图层在动画结束时立即删除,而目标内容还未准备好,中间便可能出现空白。候选修复是协调退出与内容就绪,不是随意延迟固定毫秒数。
追问与回答
设置透明背景能解决吗?
只有在证据表明问题来自不合适的背景绘制时,它才可能是方案的一部分。透明也可能让下面的空白或旧内容露出来,并不会自动让新窗口准备好。因此我会先确认是哪一层在显示黑色,再判断背景、层级和交接时序各自的作用,避免用视觉遮掩代替真正的内容就绪问题。
为什么加延迟不够?
固定延迟只是猜测目标多久能准备好。负载、设备和内容变化后,延迟短了仍会黑屏,长了又可能出现旧画面停留。更稳妥的是依据实际就绪信号协调交接,并保留超时恢复。延迟可以用于临时验证时序假设,但不能仅凭它让现象消失,就认定已经有了稳定修复。
易混淆点
不要把“等第一帧”简化为 Activity.onResume、一次 draw 返回或固定 sleep;这些不一定代表用户已看到目标帧。
参考资料
内容来源
- Android 技术札记 · 原条目
display-black