Fragment无法通过ViewModel观察Repository中LiveData数值变化问题
问题原因及解决方案
1. Repository实例不唯一(核心原因)
你在ViewModel的构造方法中每次都新建了独立的Repository实例,每个Repository内部的postUploaded是实例独有的成员变量,你触发Firebase上传逻辑所用的Repository实例,和当前ViewModel持有的不是同一个,自然无法观察到另一个实例中LiveData的数值变化。
修复方案
将Repository改为单例模式,全局共用同一个实例,避免重复创建:
// Repository类改成单例实现示例 class Repository private constructor(private val application: Application) { companion object { @Volatile private var INSTANCE: Repository? = null fun getInstance(application: Application): Repository { return INSTANCE ?: synchronized(this) { INSTANCE ?: Repository(application).also { INSTANCE = it } } } } // 原有逻辑不变 }
ViewModel中获取Repository时调用单例方法:
private val authAppRepository: Repository = Repository.getInstance(application)
2. 工作线程非法调用setValue
Firebase Firestore的addOnSuccessListener回调默认运行在后台工作线程,而MutableLiveData.setValue()方法只能在主线程调用,工作线程调用会导致赋值失效甚至崩溃。
修复方案
把赋值逻辑改成使用postValue()方法,支持在任意线程调用,自动切换到主线程分发数值:
.addOnSuccessListener { postUploaded.postValue(true) }
3. ViewModel初始化传入错误的Application实例
你创建ViewModel工厂时传入了自行新建的Application()实例,不是App运行时的实际Application实例,会导致ViewModel生命周期绑定异常,无法正常和当前Fragment关联。
修复方案
改用宿主上下文自带的Application实例初始化ViewModel:
mViewModel = ViewModelProvider( this, ViewModelProvider.AndroidViewModelFactory.getInstance(requireActivity().application) ).get(UploadFragmentViewModel::class.java)
可选优化建议
不要对外暴露MutableLiveData类型,避免外部随意修改内部状态,降低不可预期风险:
// Repository中修改为: private val _postUploaded = MutableLiveData<Boolean>() val postUploaded: LiveData<Boolean> = _postUploaded // ViewModel中修改为: val postUploaded: LiveData<Boolean> = authAppRepository.postUploaded
内容的提问来源于stack exchange,提问作者Shivam
相关产品推荐
相关产品推荐

