Можно ли вызвать ObserverForever () для Livedata, возвращаемого Transformations.map () внутри ViewModel?

Я попытался использовать LiveData Transformations.map (), чтобы проверить результат и обновить пользовательский интерфейс. Но обратный вызов Transformations.map () не запускается без наблюдателя.

Так это хороший способ вызвать observeForever {} для живых данных, возвращаемых Tranformations.map? И удалить оберверы на onCleared на ViewModel?

private lateinit var map: LiveData<Unit>

    fun getAppConfiguration(): MutableLiveData<TopRatedMoviesResponse> {
        progressDialogVisibleLiveData.postValue(true)

        val appConfigurationLiveData = MutableLiveData<TopRatedMoviesResponse>()

        val appConfigurationSourceLiveData : MutableLiveData<DataResult> = splashScreenRepository.getAppConfiguration(getApplication())

        map = Transformations.map(appConfigurationSourceLiveData) { dataResult ->
            progressDialogVisibleLiveData.postValue(false)

            when (dataResult) {
                is DataResultSuccess -> {
                    appConfigurationLiveData.postValue(dataResult.data as TopRatedMoviesResponse)
                }

                is DataResultFailed -> {
                    when (dataResult.errorCode) {
                        HTTPError.NO_INTERNET -> {
                            errorDialogVisibleLiveData.postValue(dataResult)
                        }

                        HTTPError.BAD_REQUEST -> {
                            errorDialogVisibleLiveData.postValue(dataResult)
                        }

                        HTTPError.UNAUTHORISED -> {
                            unAuthorisedEventLiveData.postValue(true)
                        }

                        HTTPError.FORBIDDEN, HTTPError.NOT_FOUND, HTTPError.INTERNAL_SERVER_ERROR, HTTPError.UNKNOWN -> {
                            errorDialogVisibleLiveData.postValue(dataResult)
                        }
                    }
                }
            }
        }
        map.observeForever {  }

        return appConfigurationLiveData
    }

    override fun onCleared() {
        super.onCleared()

        map.removeObserver {  }
    }

comment
Вы должны сохранить лямбда как ссылку на поле, так как я не думаю, что это будет тот же самый экземпляр лямбда.   -  person EpicPandaForce    schedule 15.02.2019


Ответы (1)


Но обратный вызов Transformations.map не запускается без наблюдателя.

Это нормально, без вызова ObserverForever () LiveData, возвращаемый Transformations.map (), не имеет никого, кто мог бы предложить данные, которые он хранит.

Так это хороший способ вызвать наблюдениеForever {} для живых данных, возвращаемых Tranformations.map?

Глядя на то, что вы делаете в этом методе, ответ будет отрицательным, это не то, как вы используете Transformations.map (). Цель этого метода - применить некоторые изменения к значениям, передаваемым исходным LiveData, до того, как это значение будет представлено наблюдателю. В вашем случае вам нужно простое изменение типа (с dataResult.data на TopRatedMoviesResponse) вместе с запуском некоторой ошибки LiveDatas, когда что-то пошло не так. Проверьте код ниже:

fun getAppConfiguration(): MutableLiveData<TopRatedMoviesResponse> {
    progressDialogVisibleLiveData.postValue(true)
    val appConfigurationSourceLiveData : MutableLiveData<DataResult> = splashScreenRepository.getAppConfiguration(getApplication())
    return Transformations.map(appConfigurationSourceLiveData) { dataResult ->
            progressDialogVisibleLiveData.postValue(false)
            when (dataResult) {
                is DataResultSuccess -> {
                    dataResult.data as TopRatedMoviesResponse
                }
                is DataResultFailed -> {
                    when (dataResult.errorCode) {                        
                        HTTPError.UNAUTHORISED -> {
                            unAuthorisedEventLiveData.postValue(true)
                        }
                        HTTPError.FORBIDDEN, HTTPError.NOT_FOUND, HTTPError.INTERNAL_SERVER_ERROR, HTTPError.UNKNOWN, HTTPError.NO_INTERNET, HTTPError.BAD_REQUEST -> {
                            errorDialogVisibleLiveData.postValue(dataResult)
                        }
                    }
                    // we have to return something even if an error occured
                    // I'm returning null, your UI should handle this
                    null 
                }                   
            }
     }
}

Также ознакомьтесь с руководством по архитектуре, чтобы узнать об альтернативных способах обработки данных и ошибок. с LiveData.

person user    schedule 15.02.2019