Open zicen opened 7 months ago
晚上在 MviDispatcher 内打印了一些日志:
protected suspend fun sendResult(intent: T) {
version++
Log.d("MviDispatcherKTX", "sendResult version:$version currentVersion:$currentVersion consumer:$intent")
_sharedFlow.emit(ConsumeOnceValue(value = intent))
}
private fun outputTo(lifecycleOwner: LifecycleOwner?, observer: (T) -> Unit) {
currentVersion = version
observerCount++
lifecycleOwner?.lifecycle?.addObserver(this)
lifecycleOwner?.lifecycleScope?.launch {
lifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
_sharedFlow.collect {
Log.d("MviDispatcherKTX", "_sharedFlow.collect version:$version currentVersion:$currentVersion isAllConsumed:${it.isAllConsumed} consumer:$it")
if (version > currentVersion) {
if (it.isAllConsumed) return@collect
++it.consumeCount
observer(it.value)
if (it.consumeCount == observerCount) it.isAllConsumed = true
}
}
}
}
}
打印出的日志如下:
// 进入页面
2024-01-18 21:54:03.897 8725-8725 ListFragment com.kunminx.purenote_ktx D input NoteIntent.TestCreateMsg:1
2024-01-18 21:54:03.897 8725-8725 MviDispatcherKTX com.kunminx.purenote_ktx D sendResult version:0 currentVersion:-1 consumer:com.kunminx.purenote.domain.intent.NoteIntent$TestCreateMsg@7db9635
2024-01-18 21:54:03.897 8725-8725 ListFragment com.kunminx.purenote_ktx D input NoteIntent.TestCreateMsg:2
2024-01-18 21:54:03.897 8725-8725 MviDispatcherKTX com.kunminx.purenote_ktx D sendResult version:1 currentVersion:-1 consumer:com.kunminx.purenote.domain.intent.NoteIntent$TestCreateMsg@7db9635
2024-01-18 21:54:03.982 8725-8725 MviDispatcherKTX com.kunminx.purenote_ktx D _sharedFlow.collect version:1 currentVersion:1 consumer:ConsumeOnceValue(consumeCount=0, isAllConsumed=false, value=com.kunminx.purenote.domain.intent.NoteIntent$TestCreateMsg@7db9635)
2024-01-18 21:54:03.983 8725-8725 MviDispatcherKTX com.kunminx.purenote_ktx D _sharedFlow.collect version:1 currentVersion:1 consumer:ConsumeOnceValue(consumeCount=0, isAllConsumed=false, value=com.kunminx.purenote.domain.intent.NoteIntent$TestCreateMsg@7db9635)
// 请求接口 此时将 version 变更为2 currentVersion 为1 也即此时消息变为可用的了
2024-01-18 21:54:04.037 8725-8725 MviDispatcherKTX com.kunminx.purenote_ktx D sendResult version:2 currentVersion:1 consumer:GetNoteList(notes=[Note(id=551b8d57-1cef-4752-8bd2-ac849b440a51, title=hdhdhdhejjeje, content=orikfjfjfjfn, createTime=1704288384456, modifyTime=1704355889918, type=2), Note(id=9ce07f7f-4cf2-408f-8c2c-c11a8556d919, title=hahaha, content=jdjdjjejrjr, createTime=1704288376241, modifyTime=1704288412812, type=0), Note(id=2c92b67f-235b-4dec-9526-d8cb42491ccc, title=, content=, createTime=1704288400123, modifyTime=1704288400123, type=0)])
2024-01-18 21:54:04.037 8725-8725 MviDispatcherKTX com.kunminx.purenote_ktx D _sharedFlow.collect version:2 currentVersion:1 consumer:ConsumeOnceValue(consumeCount=0, isAllConsumed=false, value=GetNoteList(notes=[Note(id=551b8d57-1cef-4752-8bd2-ac849b440a51, title=hdhdhdhejjeje, content=orikfjfjfjfn, createTime=1704288384456, modifyTime=1704355889918, type=2), Note(id=9ce07f7f-4cf2-408f-8c2c-c11a8556d919, title=hahaha, content=jdjdjjejrjr, createTime=1704288376241, modifyTime=1704288412812, type=0), Note(id=2c92b67f-235b-4dec-9526-d8cb42491ccc, title=, content=, createTime=1704288400123, modifyTime=1704288400123, type=0)]))
// 退到后台返回 粘性一般恢复了所有历史消息
2024-01-18 21:55:32.058 8725-8725 MviDispatcherKTX com.kunminx.purenote_ktx D _sharedFlow.collect version:2 currentVersion:1 consumer:ConsumeOnceValue(consumeCount=0, isAllConsumed=false, value=com.kunminx.purenote.domain.intent.NoteIntent$TestCreateMsg@7db9635)
2024-01-18 21:55:32.058 8725-8725 ListFragment com.kunminx.purenote_ktx D output NoteIntent.TestCreateMsg:com.kunminx.purenote.domain.intent.NoteIntent$TestCreateMsg@7db9635
2024-01-18 21:55:32.058 8725-8725 MviDispatcherKTX com.kunminx.purenote_ktx D _sharedFlow.collect version:2 currentVersion:1 consumer:ConsumeOnceValue(consumeCount=0, isAllConsumed=false, value=com.kunminx.purenote.domain.intent.NoteIntent$TestCreateMsg@7db9635)
2024-01-18 21:55:32.058 8725-8725 ListFragment com.kunminx.purenote_ktx D output NoteIntent.TestCreateMsg:com.kunminx.purenote.domain.intent.NoteIntent$TestCreateMsg@7db9635
2024-01-18 21:55:32.058 8725-8725 MviDispatcherKTX com.kunminx.purenote_ktx D _sharedFlow.collect version:2 currentVersion:1 consumer:ConsumeOnceValue(consumeCount=1, isAllConsumed=true, value=GetNoteList(notes=[Note(id=551b8d57-1cef-4752-8bd2-ac849b440a51, title=hdhdhdhejjeje, content=orikfjfjfjfn, createTime=1704288384456, modifyTime=1704355889918, type=2), Note(id=9ce07f7f-4cf2-408f-8c2c-c11a8556d919, title=hahaha, content=jdjdjjejrjr, createTime=1704288376241, modifyTime=1704288412812, type=0), Note(id=2c92b67f-235b-4dec-9526-d8cb42491ccc, title=, content=, createTime=1704288400123, modifyTime=1704288400123, type=0)]))
可以基本推断出是由于这行代码引起: 注释掉之后正常。说明确实存在这种极限case缺陷。
感谢你的反馈。根据你提供的信息,个人认为问题是由于 input 发生在 requester 被注册前所致。
fragment 的 view 无法在 onCreate 阶段直接获得,导致 fragment 基类的 onOutput 抽象方法的执行位置无法和 activity 一样,按一定顺序统一放在基类的 onCreate 方法中。目前 fragment 基类中的 onOutput 抽象方法是置于 onViewCreated 方法中,当人们误在 fragment 子类的 onCreate 中 input 数据,就会造成上述现象。
目前暂未找到更好的办法,只能是开发者自己注意,避免在 onOutput 注册前,发生 input。 如有自己验证过可行的变通方案,欢迎分享。
代码修改截图: 就是新增了一个测试事件在 onCreate 生命周期的时候调用 日志截图: APP 在前台的时候没响应 onCreate 发的事件是符合预期的,因为事件的收集是在 onStart 阶段,但是此时退到后台再返回,情况就不对了,这时候把 onCreate 发的事件响应了。