Mvvm MediatorLiveData onChanged未被调用,尽管正在观察它

Mvvm MediatorLiveData onChanged未被调用,尽管正在观察它,mvvm,mediatorlivedata,Mvvm,Mediatorlivedata,在NetworkBoundResource文件中,直到Log.dTAG行init:called开始工作,但是 results.addSource不工作,尽管我在RestaurantViewModel类中观察到它,而在NetworkBoundResource中观察结果的其他MediatorLiveData正在我的活动中观察到 如果我运行应用程序,则不会发生任何事件。没有错误。很明显,有些东西不见了,但我找不到它是什么。任何答案都会很有帮助。提前谢谢你 RestaurantViewModel.kt餐

在NetworkBoundResource文件中,直到Log.dTAG行init:called开始工作,但是 results.addSource不工作,尽管我在RestaurantViewModel类中观察到它,而在NetworkBoundResource中观察结果的其他MediatorLiveData正在我的活动中观察到

如果我运行应用程序,则不会发生任何事件。没有错误。很明显,有些东西不见了,但我找不到它是什么。任何答案都会很有帮助。提前谢谢你

RestaurantViewModel.kt餐厅

restaurantposition.kt中的searchByRestaurantId函数

NetworkBoundResource.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)) }
        }
    }
}