实时数据返回旧响应,然后在用户注册中使用改装始终显示新响应



问题声明:当我按下注册新用户的注册按钮时,它会在toast中显示来自实时数据的注册成功响应,但当我尝试执行相同的按钮触发时,它再次显示来自API&然后在toast中显示API的电话号码存在响应。这意味着旧的响应也通过实时数据返回。那么,我该如何解决这个递归实时数据响应返回问题呢?

这是了解问题的问题视频链接请查看此处https://drive.google.com/file/d/1-hKGQh9k0EIYJcbInwjD5dB33LXV5GEn/view?usp=sharing

需要ARGENT帮助

我的Api接口

interface ApiServices {
/*
* USER LOGIN (GENERAL USER)
* */
@POST("authentication.php")
suspend fun loginUser(@Body requestBody: RequestBody): Response<BaseResponse>
}

我的存储库类

class AuthenticationRepository {
var apiServices: ApiServices = ApiClient.client!!.create(ApiServices::class.java)
suspend fun UserLogin(requestBody: RequestBody) = apiServices.loginUser(requestBody)
}

我的视图模型类

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) {}
}

您的registerResponse实时数据在按钮点击监听器内观察,所以这就是它观察两次的原因!您的寄存器响应实时数据应该观察按钮外的数据点击监听器-

override fun onCreated(savedInstance:Bundle?({工具栏控制器((

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")
}
}
}

LiveData是一个状态持有者,它实际上并不意味着要用作事件流。然而,有很多关于这个主题的文章描述了可能的解决方案,包括从谷歌样本中获取的SingleLiveEvent实现。

但到目前为止,kotlin协同程序库提供了更好的解决方案。特别是,通道对事件流非常有用,因为它们实现了扇出行为,因此可以有多个事件消费者,但每个事件只处理一次。Channel.receiveAsFlow可以非常方便地将流公开为流。否则,SharedFlow是事件总线实现的一个很好的候选者。只需小心使用replayextraBufferCapacity参数即可。

最新更新