我在android应用程序中遵循MVVM架构。(https://developer.android.com/jetpack/guide)。我的所有存储库函数都返回一个NetworkBoundResource对象。你可以从jetpack指南链接中阅读更多关于这个设计实现的信息,或者在这里查看谷歌的示例项目
在这个特殊的问题中,当我按下屏幕时,我试图通过网络重新获取信息。
当前工作实施
片段侦听器(屏幕下拉时触发(
binding.refresh.setOnRefreshListener {
profileViewModel.refreshUserProfile()
}
然后在我的ViewModel中,我有一个MutableLiveData,它更新了这个调用的函数的值
private val _refresh = MutableLiveData<Boolean>()
fun refreshUserProfile() {
_refresh.value = true
}
当_refresh.value
发生变化时,会触发switchMap
val currentUserProfile: LiveData<Resource<UserProfile>> = _refresh.switchMap {
if (it) {
repository.getCurrentUserProfile(_username.value.toString())
} else {
AbsentLiveData.create()
}
}
存储库功能
fun getCurrentUserProfile(username: String): LiveData<Resource<UserProfile>> {
return object : NetworkBoundResource<UserProfile, UserProfile>(AppExecutors.getInstance()) {
override fun saveCallResult(item: UserProfile) {
userProfileDao.update(item)
}
override fun shouldFetch(data: UserProfile?): Boolean {
return true
}
override fun loadFromDb(): LiveData<UserProfile> {
return userProfileDao.load(username)
}
override fun createCall(): LiveData<ApiResponse<UserProfile>> {
return networkService.userProfileService.getUserProfileAsync(
token,
username
)
}
}.asLiveData()
}
然后回到我的片段,我有一个关于这个currentUserProfile
ViewModel变量的观测者
profileViewModel.currentUserProfile.observe(viewLifecycleOwner, { userProfileResult ->
when (userProfileResult.status) {...}
})
我想做什么
我想跳过设置_refresh.value = true
的步骤。相反,直接观察存储库的功能如下:
val currentUserProfile: LiveData<Resource<UserProfile>> =
repository.getCurrentUserProfile(_username.value.toString())
但是这个实现不会触发片段中的观察者。
问题我不太明白为什么我的第二个实现不能触发observer。我也不确定我最初的实现是否是最佳的或正确的。我将感谢任何形式的反馈,特别是如果你熟悉这种类型的设计。
我过去也遇到过类似的问题&大多数时候,它与两件事有关:
- 插入/更新的
dao
实例与观察livedata的dao
实例不同 - 我的CCD_ 7对象被其他一些livedata&返回。简而言之,它与
dao
返回的livedata
实例不同
您可以记录实例&检查是否相同。它需要是singleton。如果您正在使用任何类型的依赖注入工具(例如Dagger(,请检查以下内容:https://stackoverflow.com/a/44958478/9715339
我的猜测是,在你的情况下,这很可能是第二种情况。当你的livedata
userProfileDao.load
被包裹在NetworkBoundResource.asLiveData()
&如果你看一下NetworkBoundResource.result
的代码,它是一个MediatorLiveData
。所以您没有在积极地监听userProfileDao
返回的相同实时数据。
为了确认这就是问题所在,您可以尝试收听从userProfileDao.load(username)
返回的直接livedata
。使用&看见
你可以试着朝那个方向挖更多。