Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

onCreate 时发送的Intent 事件在 App 从后台返回的时候被异常消费了 #6

Open
zicen opened this issue Jan 18, 2024 · 3 comments

Comments

@zicen
Copy link

zicen commented Jan 18, 2024

代码修改截图:
image
就是新增了一个测试事件在 onCreate 生命周期的时候调用
日志截图:
img_v3_0277_8a9b23b0-3aaa-4dd8-9195-7ea66197eddg
APP 在前台的时候没响应 onCreate 发的事件是符合预期的,因为事件的收集是在 onStart 阶段,但是此时退到后台再返回,情况就不对了,这时候把 onCreate 发的事件响应了。

@zicen
Copy link
Author

zicen commented Jan 18, 2024

操作视频:

20240118-150659.mp4

@zicen
Copy link
Author

zicen commented Jan 18, 2024

晚上在 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)]))

可以基本推断出是由于这行代码引起:
image
注释掉之后正常。说明确实存在这种极限case缺陷。

@KunMinX
Copy link
Owner

KunMinX commented Jan 27, 2024

感谢你的反馈。根据你提供的信息,个人认为问题是由于 input 发生在 requester 被注册前所致。

fragment 的 view 无法在 onCreate 阶段直接获得,导致
fragment 基类的 onOutput 抽象方法的执行位置无法和 activity 一样,按一定顺序统一放在基类的 onCreate 方法中。目前 fragment 基类中的 onOutput 抽象方法是置于 onViewCreated 方法中,当人们误在 fragment 子类的 onCreate 中 input 数据,就会造成上述现象。

目前暂未找到更好的办法,只能是开发者自己注意,避免在 onOutput 注册前,发生 input。
如有自己验证过可行的变通方案,欢迎分享。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants