场景classLink(valkey:String){enumclassPhase{OFF,ON,RETRY}varphase:PhasePhase.OFF}varactive:Link?nullvalrevisionMutableStateFlow(0L)// 连接层 state 变了就 revisionfunonPhaseChanged(){revision.valueSystem.currentTimeMillis()}funonLinkLost(){active?.phaseLink.Phase.RETRY// 不换 Link 实例只改内部 phaseonPhaseChanged()}onLinkLost()只改active!!.phase RETRY不换新Link实例。问题写法distinct 后面接 stateInvallinkFlow:StateFlowLink?revision.map{active}.distinctUntilChangedBy{${it?.key}-${it?.phase}}.stateIn(scope,SharingStarted.WhileSubscribed(),null)phase从 ON 变 RETRY 时步骤发生什么revisionemit触发整条链distinctUntilChangedBykey 从k-ON变为k-RETRY放行stateIn写.value新值仍是同一个active引用 →old new→不通知 collectdistinct 按逻辑 key去重StateFlow按引用去重——多挡一层。linkFlow.collect{link-showOnline(link?.phaseLink.Phase.ON)}collect不重跑时showOnline不会更新link?.phase虽是 getterlambda 根本没执行。.value与缓存是同一规则valsameReflinkFlow.value// 引用在// phase 已 RETRY但 StateFlow 不会为此再推一次替代shareIn(replay 1)vallinkFlow:SharedFlowLink?revision.map{active}.distinctUntilChangedBy{${it?.key}-${it?.phase}}.shareIn(scope,SharingStarted.WhileSubscribed(),replay1)distinct放行后每次向SharedFlowemit 一次不因引用相同而跳过活跃collect会再跑。stateInshareIn(replay 1)同引用、仅phase变常不通知通知晚订阅首包.valuereplay 最后一次 emit同步读.valuereplayCache.lastOrNull()或读active?.phasereplay 0时晚订阅要等下一次revision进界面可能一直没有首包。实践注意、边界与自检必须StateFlow.value且实例可变stateIn前改成不可变快照如data class Snap(val key: String?, val phase: Phase)不要直接缓存Link?。求简单、同引用phase也要推distinctUntilChangedByshareIn(replay 1)。同步读当前phase直接读active?.phase别假设热流一定会再 emit。只改active却不revisiondistinct 上游无 tick换 shareIn 也没用。订阅方if (last link) return自行挡刷新与算子无关。自检distinct 日志/key 已变而 UI 不动 → 查stateIn引用判等晚订阅无首包 → 查replay要同步态 → 读变量或快照别只盯流。