【问题标题】:LiveData observer trigger only once with empty valueLiveData 观察者仅触发一次,值为空
【发布时间】:2020-03-06 12:33:42
【问题描述】:

一切正常的 API 请求都返回响应,但是,活动观察者仅在第一次触发时使用空值,并且当响应来自请求观察者时没有看到更改。

活动:

viewModel.jobQuestions.observe(this, Observer { list ->
            list?.let {
                jobQuestionsRv.apply {
                  setAdapterData(list)
                }
            }
        })

视图模型:

class JobQuestionsViewModel @Inject constructor(private val repository: Repository) : ViewModel() {

private val _jobQuestions = MutableLiveData<List<QuestionModel>>()
val jobQuestions: LiveData<List<QuestionModel>> = _jobQuestions

init {
    _jobQuestions.postValue(repository.getQuestions())
    }
}

存储库:

override fun getQuestions(): List<QuestionModel> {

    var questionsList = ArrayList<QuestionModel>()

    apiRequests?.questions()?.enqueue(object : retrofit2.Callback<List<QuestionModel>> {
        override fun onResponse(
            call: Call<List<QuestionModel>>?,
            response: Response<List<QuestionModel>>
        ) {
            response.body()?.let {
                questionsList.addAll(response.body())

            }
        }

        override fun onFailure(call: Call<List<QuestionModel>>?, t: Throwable?) {
            questionsList.clear()

        }
    })

    return questionsList
}

【问题讨论】:

  • enqueue 是异步函数,这意味着你在调用 onResponse 之前返回空的 questionsList 。您可以在getQuestions 中使用和返回LivaData,在onResponse 中使用setValue/postValue 这个livedata 的方法
  • 是的,我试过了,它的工作,但我认为这是在 viewModel 中生成实时数据的更好解决方案,我能以某种方式实现吗?
  • 那么你必须在getQuestions 中传递回调,这些回调将在onResponseonFailure 中调用
  • 我怎样才能做到这一点?
  • 你的网络请求函数是什么类型的?

标签: android kotlin mvvm android-livedata


【解决方案1】:

如果您在观察者中获得的数据引发任何异常,那么该观察者将不会再次调用,直到您再次设置该观察者或阻止该异常。

【讨论】:

  • 我在这里问过之前检查过,没有任何例外
【解决方案2】:

如果您想从存储库中返回 LiveData,您可以执行以下操作:

在存储库中,将 questionsList 的类型更改为 MutableLiveData 并在回调返回时发布该值:

override fun getQuestions(): LiveData<QuestionModel> {

    val questionsList = MutableLiveData<List<QuestionModel>>()

    apiRequests?.questions()?.enqueue(object : retrofit2.Callback<List<QuestionModel>> {
        override fun onResponse(
            call: Call<List<QuestionModel>>?,
            response: Response<List<QuestionModel>>
        ) {
            response.body()?.let {
                questionsList.postValue(response.body())

            }
        }

        override fun onFailure(call: Call<List<QuestionModel>>?, t: Throwable?) {
            questionsList.postValue(emptyList())

        }
    })

    return questionsList
}

在 ViewModel 中,只需调用 getQuestions():

class JobQuestionsViewModel @Inject constructor(private val repository: Repository) : ViewModel() {

    val jobQuestions: LiveData<List<QuestionModel>> = repository.getQuestions()
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-10-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多