Android Kotlin:解决LiveData异步导致登录校验返回值异常问题
解决LiveData异步导致登录校验逻辑失效的问题
你的问题核心在于试图同步获取LiveData的异步回调结果:checkNumber函数刚注册观察者就立即返回初始值false,这时候API请求还在后台执行,根本没拿到服务器响应,自然无法正确判断。
正确的解决方案
把页面跳转/提示逻辑直接放到LiveData的观察者回调里,因为观察者会在API响应返回后才触发。同时要避免每次点击都重复注册观察者,建议在onViewCreated里只注册一次。
修改后的Fragment代码
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) // 提前注册LiveData观察者,仅注册一次 authRiderViewModel.response.observe(viewLifecycleOwner) { response -> Timber.d("Response: $response") handleAuthResult(response.success == true) } binding.btnContinue.setOnClickListener { val numberStr = binding.etMobileNumber.text.toString() // 先做基础格式校验 if (numberStr.isBlank()) { Toast.makeText(requireContext(), "请输入手机号", Toast.LENGTH_SHORT).show() return@setOnClickListener } val number = numberStr.toLong() Timber.d("Number: $number") // 只触发API请求,结果交给观察者处理 authRiderViewModel.authDriver(number) } } private fun handleAuthResult(isRegistered: Boolean) { if (isRegistered) { val action = LoginFragmentDirections.actionLoginFragmentToOtpFragment() findNavController().navigate(action) } else { Toast.makeText(requireContext(), "Number not registered", Toast.LENGTH_SHORT).show() } }
额外优化:避免配置变更后重复回调
如果遇到屏幕旋转等配置变更场景,普通LiveData会再次触发观察者回调,可能导致重复跳转。可以自定义SingleEventLiveData来解决这个问题:
class SingleEventLiveData<T> : MutableLiveData<T>() { private val pending = AtomicBoolean(false) override fun observe(owner: LifecycleOwner, observer: Observer<in T>) { super.observe(owner) { value -> if (pending.compareAndSet(true, false)) { observer.onChanged(value) } } } override fun setValue(value: T?) { pending.set(true) super.setValue(value) } }
然后在ViewModel中替换原有LiveData类型:
// 假设AuthResponse是你的API响应实体类 val response = SingleEventLiveData<AuthResponse>()
内容的提问来源于stack exchange,提问作者oyeraghib
相关产品推荐
相关产品推荐

