You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 05:10:33