MergeWithNextTransaction 机制解析
核心含义
mMergeWithNextTransaction 是一个事务同步标志,表示当前的 SurfaceControl.Transaction 不要立即提交给
SF,而是合并到 ViewRootImpl 的下一帧渲染事务中,确保 Surface 操作和 View 绘制在同一帧完成。
问题场景:为什么需要同步?
以 AOD 消失 → 亮屏为例:
不同步时(两帧完成): 帧 N: AOD View 消失(View 绘制) → 用户看到:锁屏裸露,没有遮挡 帧 N+1: 压黑 Layer 显示(SF Transaction)→ 用户看到:黑屏盖上 ↑ 闪了一帧锁屏!
同步时(一帧完成): 帧 N: AOD View 消失 + 压黑 Layer 显示 → 用户看到:直接从 AOD 变黑屏 (合并在同一个 SF Transaction 中) 无闪烁
代码流程
@Volatile
private var mMergeWithNextTransaction: Boolean = false
private fun mergeWithNextTransaction(show: Boolean) {
keyguardPanelViewInjector.viewRootImpl.let {
// ① 注册渲染树的帧回调——在 View 绘制完成时触发
it?.registerRtFrameCallback { frame: Long ->
mMergeWithNextTransaction = true // ② 标记:后续操作不要单独 apply
if (show) {
coverBlackScreenFade() // ③ 准备压黑的 Transaction(不 apply)
it.mergeWithNextTransaction( // ④ 合并到 ViewRootImpl 的帧事务
mScreenFadeTransaction, frame
)
} else {
hideSurface(true) // ③ 准备隐藏的 Transaction(不 apply)
it.mergeWithNextTransaction(
mScreenFadeTransaction, frame
)
}
mMergeWithNextTransaction = false // ⑤ 重置标记
}
}
}
它如何控制 apply 行为
在 showScreenFadeSurface 和 hideSurface 中,这个 flag 决定事务的提交方式:
// showScreenFadeSurface (L427-429)
if (!mMergeWithNextTransaction) {
mScreenFadeTransaction.applyAsyncUnsafe() // 普通路径:立即提交
}
// else: 不提交,留给 mergeWithNextTransaction 合并提交
// hideSurface (L475-481)
if (!mMergeWithNextTransaction) {
if (needApply) {
transaction?.applyAsyncUnsafe() // 普通路径:立即提交
}
} else {
Log.d(TAG, "ScreenFade hide ScreenFade layer next transaction")
// 不提交,等 ViewRootImpl 合并
}两种路径对比

ViewRootImpl.mergeWithNextTransaction 是什么
这是 Android Framework 提供的 API:
// ViewRootImpl.java
public void mergeWithNextTransaction(Transaction t, long frameNr) {
// 将外部 Transaction 合并到当前帧号对应的渲染事务中
// 在 RenderThread 提交帧缓冲时,一并提交给 SurfaceFlinger
}它保证了 View 树的绘制结果(如 AOD 消失)和外部 SurfaceControl 操作(如压黑 Layer 显示)在 SF 侧作为一个原子事务执行,不会出现中间状态。
一句话总结
mMergeWithNextTransaction = “别急着提交,等 View 画完一起交给 SF”,本质是用帧级事务合并来消除多个 Surface 操作之间的时序间隙,避免用户看到闪烁。