【问题标题】:LiveData in MVVM pattern with retrofit kotlinMVVM 模式中的 LiveData 与改造 kotlin
【发布时间】:2020-01-10 06:26:02
【问题描述】:

我是 MVVVM 和改造的新手,我已成功实施 MVVM,并且能够将数据从改造移动到存储库,然后从存储库移动到 ViewModel 和视图。

在执行此操作时,我遇到了一个巨大的困惑,如下所述。在第一种情况下,我的代码如下所示:

存储库:

 fun iniateOTPprocess() : LiveData<GenericResponse> {


    RetroUtils.getApiManager().listRepos().enqueue(object : RetrofitCallback() {

        override fun onResponse(call: Call<GenericResponse>, response: Response<GenericResponse>) {
            super.onResponse(call, response)

            result.value = response.body()

        }
    }

    )

  return result
}

视图模型:

 class LoginViewModel2(application: Application) : AndroidViewModel(application) {

lateinit var username: MutableLiveData<String>
lateinit var password: MutableLiveData<String>
var repository: LoginRepository = LoginRepository(application)
var data = MediatorLiveData<GenericResponse>()
var result = MutableLiveData<GenericResponse>()

init {
    data.addSource(result , Observer {
        data.postValue(it)
    })
}

fun onLoginBtnCLicked() {
    initiateOTP()
}

private fun initiateOTP() {
  result =  repository.iniateOTPprocess()
}

  fun getResponse() : MediatorLiveData<GenericResponse>{
   return data
  }
 }

Mediator 实时数据一旦更新就永远不会以这种方式更新。

但是如果我把这段代码改成

存储库

  class LoginRepository(var application: Application) {

var callback: RetrofitCallback = RetrofitCallback()
var result = MutableLiveData<GenericResponse>()

fun iniateOTPprocess() {

    RetroUtils.getApiManager().listRepos().enqueue(object : RetrofitCallback() {

        override fun onResponse(call: Call<GenericResponse>, response: Response<GenericResponse>) {
            super.onResponse(call, response)

            result.value = response.body()
        }
    }
    )
}

fun getData(): MutableLiveData<GenericResponse> {
    return result
}
}

视图模型

class LoginViewModel2(application: Application) : AndroidViewModel(application) {

lateinit var username: MutableLiveData<String>
lateinit var password: MutableLiveData<String>
var repository: LoginRepository = LoginRepository(application)
var data = MediatorLiveData<GenericResponse>()
var result = MutableLiveData<GenericResponse>()

init {
    data.addSource(repository.getData(), Observer {
        data.postValue(it)
    })
}

fun onLoginBtnCLicked() {
    initiateOTP()
}

private fun initiateOTP() {
    repository.iniateOTPprocess()
}

 fun getResponse() : MediatorLiveData<GenericResponse>{

   return data
 }
}

这段代码开始神奇地工作。在视图中,我在这两种情况下都观察到 getResponse() 方法。这里的任何人都可以帮助解决混乱,并可以解释魔术发生在哪里。提前致谢。

【问题讨论】:

  • 在您的第一个场景中,您是在观察getResponse() 之前先调用initiateOTP() 吗?
  • initiateOTP 在按钮单击时被调用,而 getResponse 在 Activity 中创建实例时被观察
  • 如果你是 MVVM 新手,想学习 MVVM,那么在这里你可以找到 MVVM 实现的示例应用。 MVVMCleanKotlin [github.com/parthpatibandha/MvvmCleanKotlin] 使用 Flickr 图像 API 的示例 android 应用程序,使用 MVVM + 清洁架构 + DI(Koin 依赖注入)的应用程序

标签: android kotlin mvvm android-livedata mutablelivedata


【解决方案1】:

在您的第一个场景中,即使您正在通过此函数更新result

private fun initiateOTP() {
  result =  repository.iniateOTPprocess()
}

您将无法观察到这个新的result 实例的变化,因为您已经在观察实例化ViewModel 时创建的第一个result 实例:

var result = MutableLiveData<GenericResponse>() // you are observing this instance
init {
    // this result never gets updated
    data.addSource(result , Observer {
        data.postValue(it)


    })

}

...

 fun getResponse() : MediatorLiveData<GenericResponse>{

    return data

 }

【讨论】:

  • 当您说“您将无法观察更改,因为您已经在观察第一次实例化 ViewModel 时创建的结果实例”时,能否请您解释一下
  • @HarrySharma 很抱歉造成混乱。我的意思是即使您在initiateOTP() 中重新分配result,由于您的init 函数,您仍然会从var result = MutableLiveData&lt;GenericResponse&gt;() 观察result 的第一个实例。希望有帮助
  • 所以在这种情况下为什么它在第二种情况下工作,在第一种情况下,存储库函数 getResponse() 返回空值,直到获取 API 响应..
  • @HarrySharma 因为您只使用了一个在存储库中更新的result 实例。此外,在第二种情况下,您可以删除 ViewModel 中的 result,因为您已经在 Repository 中拥有它
  • 谢谢你的清晰,亲爱的..在这个信息之前我在另一个世界:)
【解决方案2】:

您的代码不遵循 MVVM 模式,每个实时数据都必须有观察者, 当您在 init{} 声明该值时,它还没有准备好,因为它是异步的。 如果您更改为:

data.addSource(repository.iniateOTPprocess(), Observer {
        data.postValue(it)
})

代码可以运行,这是学习 MVVM 和 livedata 模式的最佳来源 google codelabs

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-03-02
    • 2020-03-12
    • 2020-03-05
    • 2019-05-03
    • 2021-10-30
    • 2022-09-27
    • 2019-07-23
    • 1970-01-01
    相关资源
    最近更新 更多