![](/img/trans.png)
[英]Mutable live-data give multiple response give old response from api and after give new response
[英]Live Data return old response then New response always in toast in User Registration using Retrofit
問題陳述:當我按下注冊按鈕注冊新用戶時,它會在實時數據的 toast 中顯示注冊成功響應,但是當我嘗試執行相同的按鈕觸發時,它再次顯示來自 API 的注冊成功響應消息,然后還顯示電話號碼存在響應API 吐司。 這也意味着實時數據返回舊響應。 那么我該如何解決這個遞歸實時數據響應返回問題呢?
這里是問題視頻鏈接以了解問題檢查這里https://drive.google.com/file/d/1-hKGQh9k0EIYJcbInwjD5dB33LXV5GEn/view?usp=sharing
需要阿根廷幫助
我的Api接口
interface ApiServices {
/*
* USER LOGIN (GENERAL USER)
* */
@POST("authentication.php")
suspend fun loginUser(@Body requestBody: RequestBody): Response<BaseResponse>
}
我的存儲庫 Class
class AuthenticationRepository {
var apiServices: ApiServices = ApiClient.client!!.create(ApiServices::class.java)
suspend fun UserLogin(requestBody: RequestBody) = apiServices.loginUser(requestBody)
}
我的觀點 Model Class
class RegistrationViewModel : BaseViewModel() {
val respository: AuthenticationRepository = AuthenticationRepository()
private val _registerResponse = MutableLiveData<BaseResponse>()
val registerResponse: LiveData<BaseResponse> get() = _registerResponse
/*
* USER REGISTRATION [GENERAL USER]
* */
internal fun performUserLogin(requestBody: RequestBody, onSuccess: () -> Unit) {
ioScope.launch {
isLoading.postValue(true)
tryCatch({
val response = respository.UserLogin(requestBody)
if (response.isSuccessful) {
mainScope.launch {
onSuccess.invoke()
isLoading.postValue(false)
_registerResponse.postValue(response.body())
}
} else {
isLoading.postValue(false)
}
}, {
isLoading.postValue(false)
hasError.postValue(it)
})
}
}
}
我的注冊活動
class RegistrationActivity : BaseActivity<ActivityRegistrationBinding>() {
override val layoutRes: Int
get() = R.layout.activity_registration
private val viewModel: RegistrationViewModel by viewModels()
override fun onCreated(savedInstance: Bundle?) {
toolbarController()
viewModel.isLoading.observe(this, {
if (it) showLoading(true) else showLoading(false)
})
viewModel.hasError.observe(this, {
showLoading(false)
showMessage(it.message.toString())
})
binding.registerbutton.setOnClickListener {
if (binding.registerCheckbox.isChecked) {
try {
val jsonObject = JSONObject()
jsonObject.put("type", "user_signup")
jsonObject.put("user_name", binding.registerName.text.toString())
jsonObject.put("user_phone", binding.registerPhone.text.toString())
jsonObject.put("user_password", binding.registerPassword.text.toString())
val requestBody = jsonObject.toString()
.toRequestBody("application/json; charset=utf-8".toMediaTypeOrNull())
viewModel.performUserLogin(requestBody) {
viewModel.registerResponse.observe(this){
showMessage(it.message.toString())
//return old reponse here then also new reponse multiple time
}
}
} catch (e: JSONException) {
e.printStackTrace()
}
} else {
showMessage("Please Accept Our Terms & Conditions")
}
}
}
override fun toolbarController() {
binding.backactiontoolbar.menutitletoolbar.text = "Registration"
binding.backactiontoolbar.menuicontoolbar.setOnClickListener { onBackPressed() }
}
override fun processIntentData(data: Uri) {}
}
LiveData
是一個 state 持有者,它並不是真的要用作事件 stream。 然而,有許多關於像這樣的主題的文章描述了可能的解決方案,包括從谷歌樣本中獲取的SingleLiveEvent實現。
但截至目前 kotlin 協程庫提供了更好的解決方案。 特別是,通道對於事件流非常有用,因為它們實現了扇出行為,因此您可以擁有多個事件消費者,但每個事件只會被處理一次。 Channel.receiveAsFlow可以非常方便地將 stream 公開為流。 否則, SharedFlow是事件總線實現的理想選擇。 請注意replay
和extraBufferCapacity
參數。
您的 registerResponse 實時數據在按鈕單擊偵聽器內觀察,這就是它觀察兩次的原因! 您的 registerResponse 實時數據應觀察按鈕單擊偵聽器之外的數據 -
覆蓋 fun onCreated(savedInstance: Bundle?) { toolbarController()
viewModel.isLoading.observe(this, {
if (it) showLoading(true) else showLoading(false)
})
viewModel.registerResponse.observe(this){
showMessage(it.message.toString())
}
viewModel.hasError.observe(this, {
showLoading(false)
showMessage(it.message.toString())
})
binding.registerbutton.setOnClickListener {
if (binding.registerCheckbox.isChecked) {
try {
val jsonObject = JSONObject()
jsonObject.put("type", "user_signup")
jsonObject.put("user_name", binding.registerName.text.toString())
jsonObject.put("user_phone", binding.registerPhone.text.toString())
jsonObject.put("user_password", binding.registerPassword.text.toString())
val requestBody = jsonObject.toString()
.toRequestBody("application/json; charset=utf-8".toMediaTypeOrNull())
viewModel.performUserLogin(requestBody) {
}
} catch (e: JSONException) {
e.printStackTrace()
}
} else {
showMessage("Please Accept Our Terms & Conditions")
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.