Mvvm MediatorLiveData onChanged未被调用,尽管正在观察它
在NetworkBoundResource文件中,直到Log.dTAG行init:called开始工作,但是 results.addSource不工作,尽管我在RestaurantViewModel类中观察到它,而在NetworkBoundResource中观察结果的其他MediatorLiveData正在我的活动中观察到 如果我运行应用程序,则不会发生任何事件。没有错误。很明显,有些东西不见了,但我找不到它是什么。任何答案都会很有帮助。提前谢谢你 RestaurantViewModel.kt餐厅 restaurantposition.kt中的searchByRestaurantId函数 NetworkBoundResource.ktMvvm MediatorLiveData onChanged未被调用,尽管正在观察它,mvvm,mediatorlivedata,Mvvm,Mediatorlivedata,在NetworkBoundResource文件中,直到Log.dTAG行init:called开始工作,但是 results.addSource不工作,尽管我在RestaurantViewModel类中观察到它,而在NetworkBoundResource中观察结果的其他MediatorLiveData正在我的活动中观察到 如果我运行应用程序,则不会发生任何事件。没有错误。很明显,有些东西不见了,但我找不到它是什么。任何答案都会很有帮助。提前谢谢你 RestaurantViewModel.kt餐
哦,问题解决了。在收到apiResponse之前,我从mediatorLivedata中删除了源。这就是为什么我无法调用onChanged方法。Oh问题得到解决。在收到apiResponse之前,我从mediatorLivedata中删除了源。这就是我无法调用onChanged方法的原因
class RestaurantViewModel(application: Application): AndroidViewModel(application) {
companion object {
private const val TAG = "RestaurantViewModel"
}
class Factory(private val application: Application) : ViewModelProvider.Factory {
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
return RestaurantViewModel(application) as T
}
}
private val mRestaurantRepository: RestaurantRepository = RestaurantRepository.instance(application)
private val results: MediatorLiveData<Resource<RestaurantDetail?>?> = MediatorLiveData()
val restaurantDetail: MediatorLiveData<Resource<RestaurantDetail?>?>
get() = results
fun searchByRestaurantId(resId: Int) {
executeSearch(resId)
}
private fun executeSearch(resId: Int) {
val repositorySource = mRestaurantRepository.searchByRestaurantId(resId)
results.addSource(repositorySource) { detailResource ->
if(detailResource != null) {
Log.d(TAG, "executeSearch: $detailResource")
results.value = detailResource
results.removeSource(repositorySource)
} else {
results.removeSource(repositorySource)
}
}
}
private fun subscribeObservers() {
mRestaurantViewModel?.restaurantDetail?.observe(this, Observer { detailResource ->
if (detailResource != null) {
when (detailResource.status) {
Resource.Status.SUCCESS -> {
detailResource.data?.let { restaurantDetail ->
Log.d(TAG, "subscribeObservers: $restaurantDetail")
setRestaurantProperties(restaurantDetail)
}
}
Resource.Status.ERROR -> {
}
Resource.Status.LOADING -> {
}
}
}
})
}
fun searchByRestaurantId(resId: Int): LiveData<Resource<RestaurantDetail?>?> {
return object: NetworkBoundResource<RestaurantDetail, RestaurantResponse>() {
override fun saveCallResult(item: RestaurantResponse) {
Log.d(TAG, "saveCallResult: called")
item.getRestaurant?.let { restaurantDetail ->
Log.d(TAG, "saveCallResult: $restaurantDetail")
restaurantDao!!.insertRestaurant(restaurantDetail)
}
}
override fun shouldFetch(data: RestaurantDetail?): Boolean {
return true
}
override fun loadFromDb(): LiveData<RestaurantDetail?> {
Log.d(TAG, "loadFromDb: called")
return restaurantDao!!.searchByRestaurantId(resId)
}
override fun createCall(): LiveData<ApiResponse<RestaurantResponse?>?> {
Log.d(TAG, "createCall: called")
val apiResponse = ServiceGenerator.retrofitService.searchByRestaurantId(resId)
Log.d(TAG, "createCall: $apiResponse")
return apiResponse
}
}.asLiveData
}
abstract class NetworkBoundResource<CacheObject, RequestObject> {
companion object {
private val TAG: String? = "NetworkBoundResource"
}
private var results: MediatorLiveData<Resource<CacheObject?>?> = MediatorLiveData()
init {
init()
Log.d(TAG, "NetworkBoundResource: called")
}
fun setValue(newValue: Resource<CacheObject?>?) {
if (results.value !== newValue) {
results.value = newValue
}
}
private fun init() {
// update LiveData for loading status
results.value = loading(null)
// observe LiveData source from local db
val dbSource: LiveData<CacheObject?> = loadFromDb()
Log.d(TAG, "init: called")
results.addSource(dbSource) { cacheObject ->
results.removeSource(dbSource)
if (shouldFetch(cacheObject)) {
// get data from the network
fetchFromNetwork(dbSource)
} else {
results.addSource(
dbSource
) { cacheObject -> setValue(Resource.success(cacheObject)) }
}
}
}