坑-协程-订阅时序导致收不到流
封装了一个MVI框架,极低概率出现这样一种问题:
页面A、页面B,A跳转B,B再返回A,然后A立刻再跳入B,偶现ViewModelScope.launch{}
域中的ShareFlow没有触发。
代码:
kt
abstract class BaseFlowViewModel<VS : ViewState, I : UserIntent,Changes: ReduceViewStateChange<VS>>(
application: Application,
firstViewState: VS
) : BaseViewModel(application) {
private val _viewState: MutableStateFlow<VS> = MutableStateFlow(firstViewState)
val viewState : MutableStateFlow<VS> = _viewState
private val _intent:MutableSharedFlow<I> = MutableSharedFlow(extraBufferCapacity = 5, onBufferOverflow=BufferOverflow.DROP_OLDEST)
protected abstract suspend fun realSendIntent(intent: I)
protected abstract suspend fun catchError(throwable: Throwable)
fun sendIntent(intent: I){
Log.d("wuxu","sendIntent!!!")
viewModelScope.launch {
_intent.emit(intent)
}
}
init {
viewModelScope.launch(Dispatchers.IO+SupervisorJob()) {
Log.d("wuxu","init!!!")
_intent
.onEach {
Log.d("wuxu","viewModelScope onEach $it")
realSendIntent(it)
}
.catch {
catchError(it)
}
.collect()
}
}
}
猜想原因只能有三个:
- scope被cancel;- 通过源码及日志输出判断,每次页面进入都会创建新的ViewModelScope,不存在cancel的情况;
- 协程域异常;- 这个我使用的是SupervisorJob(),所以排除
- collect()订阅,比emit晚。 - 最终确定是这个
最终日志输出:
正常:init->sendIntent 出问题时:sendIntent->init ,此时没有collect,导致无法触发流。