Compose Recomposer中awaitWorkAvailable恢复时机
问题解答
你对workContinuation恢复逻辑的判断存在偏差,它的常规恢复路径根本不需要等待effectJob整体执行完成,也不依赖close()方法调用。
核心逻辑拆解如下:
awaitWorkAvailable()挂起前会先做前置检查:如果当前已经存在待处理的重组失效记录、待执行的副作用任务、待应用的状态变更,会直接返回,不会进入挂起流程。只有当所有任务队列都为空时,才会将当前协程的Continuation实例赋值给workContinuation进入挂起,同时给effectJob注册invokeOnCompletion回调作为兜底。- 你提到的
effectJob的invokeOnCompletion回调只是销毁兜底逻辑,不是正常运行时的唤醒路径:这个回调只会在effectJob进入终态(正常完成/被取消)时触发,作用是在Recomposer整个生命周期结束时,把挂起的协程resume掉避免泄漏,对应你说的生命周期绑定场景下的cancel调用、以及withRunningRecomposer里的close调用,都属于退出重组循环的销毁流程,和正常工作流的唤醒无关。 - 正常运行过程中
workContinuation的恢复是主动直接触发的,不需要等effectJob回调:只要有新的工作产生,对应逻辑分支会直接取出当前保存的workContinuation实例调用resume,同时把引用置空,让awaitWorkAvailable()结束挂起,回到外层while循环处理新任务。
常规场景下直接触发workContinuation恢复的场景包括:
- 任意Composable触发重组失效,调用
Recomposer.invalidate()时 - 新的副作用任务(LaunchedEffect、SideEffect、DisposableEffect等)被提交到待执行队列时
- 绑定的Choreographer帧信号到达,需要执行帧对齐的重组流程时
- 快照提交产生了状态变更通知,需要触发对应作用域的重组时
补充说明:withRunningRecomposer只是封装了Recomposer启动-销毁生命周期的工具方法,Android实际生产环境中Compose是通过ComposeView挂载时手动启动Recomposer的运行循环、绑定到View树的Lifecycle,页面销毁时才会cancel对应的effectJob走兜底退出逻辑,和运行时的唤醒流程完全独立。
内容的提问来源于stack exchange,提问作者Ji Sungbin
相关产品推荐
相关产品推荐

