Android中SuccessListener内变量赋值外部无法生效问题求助
Android全局变量在异步监听器外部未更新的问题
我在Android开发中声明了一个全局变量:
var userWeight:Double = 0.0
尝试通过getUserDetails()的addOnSuccessListener为该变量赋值时,发现监听器内部能正确更新变量值,但在监听器外部变量仍保持默认值0.0。
相关代码及日志情况
- 仅监听器内打印的代码:
getUserDetails().addOnSuccessListener { document-> userWeight = document.toObject(User::class.java)!!.weight.toDouble() Log.d("temperory","$userWeight") }
此时日志显示userWeight已被正确赋值(监听器内输出了预期的体重数值)
- 监听器内外都打印的代码:
getUserDetails().addOnSuccessListener { document-> userWeight = document.toObject(User::class.java)!!.weight.toDouble() Log.d("temperory","$userWeight") } Log.d("weightuser","$userWeight")
此时日志显示:监听器内输出正确数值,但外部的weightuser日志仍输出0.0
问题原因
这是因为getUserDetails()是异步操作,addOnSuccessListener中的代码会在异步任务完成后才执行,而监听器外部的Log.d("weightuser","$userWeight")会在异步任务开始前立刻执行,此时userWeight还未被赋值,仍然是初始的默认值。
解决方案
所有依赖userWeight的逻辑都需要放在异步回调内部,或者使用协程、LiveData等方式处理异步结果:
方案1:把业务逻辑移到监听器内部
getUserDetails().addOnSuccessListener { document-> userWeight = document.toObject(User::class.java)!!.weight.toDouble() Log.d("temperory","$userWeight") // 在这里处理需要用到userWeight的逻辑,比如更新UI、计算操作等 updateUIWithWeight(userWeight) }
方案2:使用Kotlin协程(推荐)
将异步回调包装为挂起函数,在协程作用域中调用:
// 包装getUserDetails为挂起函数 suspend fun getUserDetailsSuspend(): Document { return suspendCoroutine { continuation -> getUserDetails() .addOnSuccessListener { continuation.resume(it) } .addOnFailureListener { continuation.resumeWithException(it) } } } // 在协程作用域内执行(比如Activity/Fragment的lifecycleScope) lifecycleScope.launch { try { val document = getUserDetailsSuspend() userWeight = document.toObject(User::class.java)!!.weight.toDouble() Log.d("weightuser","$userWeight") // 后续依赖userWeight的逻辑写在这里 } catch (e: Exception) { // 处理异步请求失败的情况 } }
方案3:使用LiveData监听变量变化
通过LiveData自动感知数值更新,触发后续逻辑:
val userWeightLiveData = MutableLiveData<Double>(0.0) // 在监听器中更新LiveData getUserDetails().addOnSuccessListener { document-> val weight = document.toObject(User::class.java)!!.weight.toDouble() userWeightLiveData.value = weight Log.d("temperory","$weight") } // 观察LiveData的变化 userWeightLiveData.observe(this) { weight -> // 数值更新时会自动触发这里的逻辑 Log.d("weightuser","$weight") updateUIWithWeight(weight) }
内容的提问来源于stack exchange,提问作者Jadu
相关产品推荐
相关产品推荐

