Mvvm LIveData每次从Acity和以前的数据中观察两次以上
我遵循MVVM登录API,通过改进,我的问题是livedata被观察了两次以上,并且在从活动中观察时总是发出以前的响应,但在存储库中它给出了正确的响应 我从stackoverflow和其他网站尝试了很多解决方案,但仍然没有成功,我也尝试了删除观察员,但仍然获得了以前的数据,因此请建议一个可行的解决方案,我将在下面发布我的代码 LoginActivity.ktMvvm LIveData每次从Acity和以前的数据中观察两次以上,mvvm,retrofit,android-livedata,observers,mutablelivedata,Mvvm,Retrofit,Android Livedata,Observers,Mutablelivedata,我遵循MVVM登录API,通过改进,我的问题是livedata被观察了两次以上,并且在从活动中观察时总是发出以前的响应,但在存储库中它给出了正确的响应 我从stackoverflow和其他网站尝试了很多解决方案,但仍然没有成功,我也尝试了删除观察员,但仍然获得了以前的数据,因此请建议一个可行的解决方案,我将在下面发布我的代码 LoginActivity.kt private lateinit var loginViewModel: LoginViewModel loginViewModel =
private lateinit var loginViewModel: LoginViewModel
loginViewModel = ViewModelProvider(this, ViewModelProvider.NewInstanceFactory()).get(
LoginViewModel::class.java
)
loginViewModel.login(userEmail, pwd)
loginViewModel.getLoginRepository().observe(this, Observer {
val loginResult = it ?: return@Observer
val accessToken = loginResult.user?.jwtToken.toString()
})
val statusMsgObserver = Observer<String> { statusMsg ->
showToast(statusMsg)
})
val errorMsgObserver = Observer<String> { errorMsg ->
// Update the UI
showToast(errorMsg)
})
loginViewModel.getStatusMessage()?.observe(this, statusMsgObserver)
loginViewModel.getErrorStatusMessage()?.observe(this, errorMsgObserver)
在LoginActivity中,当我观察loginResult时,它首先给出先前发出的accessToken,然后再次调用,并给出当前accessToken,类似地,每次调用observer的次数超过两次。
但是在存储库中,它提供了最新的数据,请检查我的代码并建议我必须在哪里更正才能获得正确的最新livedata最后我找到了解决方案,在LoginRepository中,我在doLogin()外部声明了responseData,它应该在doLogin()内部声明 由于不在方法范围内,它总是先给出以前的数据,然后给出当前的数据, 一旦我声明内部方法的问题已经解决,现在它的工作是完美的
class LoginViewModel: ViewModel() {
private var loginRepository: LoginRepository? = null
private var _mutableLiveData = MutableLiveData<LoginAPIResponse?>()
val liveData: LiveData<LoginAPIResponse?> get() = _mutableLiveData
private var responseMsgLiveData:MutableLiveData<String>?= null
private var errorResponseMsgLiveData:MutableLiveData<String>?= null
fun login(username: String, password: String) {
loginRepository = LoginRepository.getInstance()!!
/* Query data from Repository */
//val _mutableLiveData: MutableLiveData<Response<LoginAPIResponse?>?>? = loginRepository?.doLogin(username, password)
_mutableLiveData = loginRepository?.doLogin(username, password)!!
responseMsgLiveData = loginRepository?.respMessage!!
errorResponseMsgLiveData = loginRepository?.loginResponseErrorData!!
}
fun getLoginRepository(): LiveData<LoginAPIResponse?> {
return liveData
}
fun getStatusMessage(): LiveData<String>? {
return responseMsgLiveData
}
fun getErrorStatusMessage(): LiveData<String>? {
return errorResponseMsgLiveData
}
}
class LoginRepository {
private val loginApi: ApiEndpoints = RetrofitService.createService(ApiEndpoints::class.java)
val responseData = MutableLiveData<LoginAPIResponse?>()
var respMessage = MutableLiveData<String>()
var loginResponseErrorData = MutableLiveData<String>()
fun doLogin(username: String, password: String)
: MutableLiveData<LoginAPIResponse?> {
respMessage.value = null
loginResponseErrorData.value = null
val params = JsonObject()
params.addProperty("email", username)
params.addProperty("password",password)
val jsonParams = JsonObject()
jsonParams.add("user",params)
loginApi.loginToServer(jsonParams).enqueue(object : Callback<LoginAPIResponse?> {
override fun onResponse( call: Call<LoginAPIResponse?>, response: Response<LoginAPIResponse?> ) {
responseData.value = response.body()
respMessage.value = RetrofitService.handleError(response.code())
val error = response.errorBody()
if (!response.isSuccessful) {
val errorMsg = error?.charStream()?.readText()
println("Error Message: $errorMsg")
loginResponseErrorData.value = errorMsg
} else {
println("API Success -> Login, $username, ${response.body()?.user?.email.toString()}")
}
}
override fun onFailure(call: Call<LoginAPIResponse?>, t: Throwable) {
println("onFailure:(message) "+t.message)
loginResponseErrorData.value = t.message
responseData.value = null
}
})
return responseData
}
companion object {
private var loginRepository: LoginRepository? = null
internal fun getInstance(): LoginRepository? {
if (loginRepository == null) {
loginRepository = LoginRepository()
}
return loginRepository
}
}
}
override fun onDestroy() {
super.onDestroy()
loginViewModel.getLoginRepository()?.removeObservers(this)
this.viewModelStore.clear()
}