【问题标题】:Handling error flow in single activity MVVM architecture: observers isn't triggered处理单活动 MVVM 架构中的错误流:不触发观察者
【发布时间】:2019-07-30 14:12:01
【问题描述】:

我在单活动应用程序中使用 MVVM。作为错误流的可能解决方案,我决定使用活动作为错误表示的聚合点(我认为这种情况下的活动是最合适的地方,因为它是单个活动场景中任何其他视图的基本视图)。我正在使用 SingleLiveEvent 传递错误(取自 here 的 SingleLiveEvent 实现)。

但在我的情况下,我没有收到来自我的 ViewModel 的任何错误更新。 作为我的流程示例:

MessageDialogViewModel.kt

class MessageDialogViewModel(application: Application) : AndroidViewModel(application), MessageApi {
    val TAG: String = "DialogViewModel: "

    val message: MutableLiveData<String> = MutableLiveData()
    val errorLiveEvent: SingleLiveEvent<BaseCommand> = SingleLiveEvent()


    override fun sendMessage() {
        Log.i(TAG, " sendMessage: start")
        if (message.value.isNullOrBlank()) {
            Log.i(TAG, " sendMessage: blank")
            errorLiveEvent.value = BaseCommand.Error(null, "Message cannot be empty")
        } else {
            Log.i(TAG, " sendMessage: ${message.value}")
            Repository.getInstance(getApplication()).sendMessage(message.value!!)
        }
    }
}

MainActivity.kt

     private val loginViewModel: LoginViewModel by lazy {
            ViewModelProviders.of(this).get(LoginViewModel::class.java)
        }

        private val mainTaskViewModel: MainTaskViewModel by lazy {
            ViewModelProviders.of(this).get(MainTaskViewModel::class.java)
        }

        private val messageDialogViewModel: MessageDialogViewModel by lazy {
            ViewModelProviders.of(this).get(MessageDialogViewModel::class.java)
        }
//////
override fun onResume() {
        super.onResume()
        //fixme merge observers
        loginViewModel.singleLiveEvent.observe(this,
            Observer {
                when (it) {
                    is BaseCommand.Success -> {
                        navigate()
                    }
                    is BaseCommand.Error -> showDialog(
                        errorTitle = it.error?.title,
                        errorMessage = it.error?.desc
                    )


                }
            })
        mainTaskViewModel.errorLiveEvent.observe(this,
            Observer {
                when (it) {
                    is BaseCommand.Success -> {

                    }
                    is BaseCommand.Error -> {
                        showToast(it.error)
                        if (it.error?.code == 500) {
                            navController.navigate(R.id.action_mainTaskFragment_to_loginFragment)
                        }
                    }
                }

            }

        )

        messageDialogViewModel.errorLiveEvent.observe(this,
            Observer {

                Log.i(TAG,"messageDialogViewModel.errorLiveEvent")
                when (it) {
                    is BaseCommand.Success -> {

                    }
                    is BaseCommand.Error -> {
                        showToast(null, it.errorMessage)
                    }
                }
            })

    }

在我的 MainActivity 中没有收到任何内容。 任何有关更好的架构解决方案的帮助或建议表示赞赏。

【问题讨论】:

  • 我认为在 mvvm 概念中,它只支持将 ViewModel 一对一绑定到 UI,但在存储库内部,您可以访问来自其他数据源或 DAO 的许多资源。这就是为什么你需要注入你需要的存储库
  • @NandaZ 感谢您的评论,它让我想到了实现 MainActivityViewModel 以传递错误消息,但我仍然不知道为什么在这种情况下我无法接收到观察者的数据。
  • 因为你从不调用这个方法sendMessage()
  • @NandaZ 这个方法绑定到 MessageDialogFragment 布局
  • 你能不能把SingleLiveEvent改成MutableLiveData看看能不能用?此外,与问题无关,但在onResume 中调用观察是一个坏主意。如果您转到其他活动或其他应用程序并返回活动,它将创建重复的观察者。

标签: android kotlin android-livedata android-mvvm


【解决方案1】:

使用errorLiveEvent.setValue(BaseCommand.Error(null, "Message cannot be empty")) 代替errorLiveEvent.value = BaseCommand.Error(null, "Message cannot be empty")

【讨论】:

  • 谢谢,我尝试打开 postValue。没有区别。
  • 我结帐SingleLiveEvent,我认为您需要致电errorLiveEvent.setValue(BaseCommand.Error(null, "Message cannot be empty")) insted of errorLiveEvent.value = BaseCommand.Error(null, "Message cannot be empty")
  • 改变了答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-09-16
  • 1970-01-01
  • 1970-01-01
  • 2020-02-21
  • 2020-05-22
  • 2020-08-09
  • 1970-01-01
相关资源
最近更新 更多