【问题标题】:StateFlow don't emit when the new value same last value当新值与上一个值相同时,StateFlow 不会发出
【发布时间】:2021-01-06 08:26:26
【问题描述】:

我有一个登录表单。我使用StateFlowLoginResult(调用API 后)从ViewModel 发送到Activity。在活动中,如果登录失败,我将显示一个错误对话框。
它第一次运行良好,但从我第二次登录失败后,错误对话框将不再显示。我在StateFlow 上测试了.value.emit

private val _loginResult = MutableStateFlow(LoginResult())
val loginResult: StateFlow<LoginResult> = _loginResult

fun login(email: String, password: String) {
    viewModelScope.launch {
        when (val result = loginRepository.login(email, password)) {
            is Result.Fail-> {
                _loginResult.value = LoginResult(error = "Login failed")
                // _loginResult.emit(LoginResult(error = "Login failed")) same issue
            }
            ...
       }
   }
}

【问题讨论】:

  • StateFlow 不会发出重复值。您可以使用 SharedFlow 来解决您的问题。
  • @OmidFaraji 是的,我已经在我的回答中解决了这个问题。我需要一些时间来解决这个问题,所以我在这里发布它

标签: android kotlin kotlin-stateflow sharedflow


【解决方案1】:

对于这种情况,我使用SharedFlow,所以我的Activity 仍然能够收集新值,即使它与最后一个值相同

private val _loginResult = MutableSharedFlow<LoginResult>()
val loginResult: SharedFlow<LoginResult> = _loginResult

...
_loginResult.emit(LoginResult(error = "Login failed"))

另一个可能但不好的解决方案是将我当前的data class LoginResult(...) 更改为class LoginResult。那么LoginResult 的每个新实例都会有所不同

【讨论】:

    【解决方案2】:

    这是默认设置。您可以做的是在登录过程中发出一个值,然后发出结果。这样你就会有一个像这样的序列:

    in_progress -&gt; error -&gt; in_progress -&gt; error

    in_progressloading 或其他任何东西发出时,应用程序通常会显示一个微调器或其他东西。

    【讨论】:

      猜你喜欢
      • 2011-10-13
      • 2019-09-23
      • 1970-01-01
      • 2018-06-25
      • 1970-01-01
      • 1970-01-01
      • 2023-01-27
      • 2021-07-02
      • 1970-01-01
      相关资源
      最近更新 更多