对于API的一次点击,ViewModel观察多次运行

时间:2019-12-30 09:02:52

标签: android rx-java rx-android android-livedata observers

我有一个图表片段和一个开关。在选择开关时,需要再次使用新值来点击API,并需要更新图表,API代码如下所示:

   private fun hitSecondChartApi(country: String, category: String, market: String, weightKpi: String) {

        userModel.getResponseShareSecondChartData(country, category, market, weightKpi)
        Log.e(TAG, "Inside hitsecondchartapi: "+ country+":"+category+":"+market+":"+weightKpi)
        userModel.responseSecondChartData.observe(this,
                Observer {
                    Log.e(TAG, "Second chart data: " + it.toString())
                    Utils.debugger("FRAG ", "$it")
                    secondChartData = it!!
                    if (it.size > 0) {
                        splitSecondParentList(it!!)
                    } else
                        Utils.showLongToast(requireActivity(), "No Data for Distribution")
//                    userModel.responseSecondChartData.removeObservers(this)
                })
    }

现在这里的问题是“ 当我打开/关闭开关时观察器正在运行多次,并且它还会先向我提供先前的API请求的值,然后再向我提供当前API的值”例如,当我将开关关闭时,仍会再次收到我在“打开”状态下收到的响应,反之亦然。就像堆栈一样。

例如:开关已打开:响应关闭->响应关闭->响应打开->响应打开->响应打开

开关已关闭:响应打开->响应打开->响应关闭->响应关闭->响应关闭

对于一个变通办法,我试图删除观察者,您也可以在上面的代码的注释行中看到该观察者,但是它有一个缺陷,因为它只会运行一次,并且我可能会也可能不会从中获得当前的API响应。

我可以做的一件事是过滤掉响应,但是我需要针对此问题进行适当的修复,因为在此情况下,我应该只接收当前的API响应,所以只能运行一次,因为我无法过滤掉其他API。

所以请帮助我解决这个问题。

1 个答案:

答案 0 :(得分:1)

每次调用hitSecondChartApi()时,新的观察者将附加到LiveData上,这些重复的观察者会导致意外结果。 SingleEventSingleLiveData之类的解决方案可以从技术上隐藏此效果,但不能消除根本原因。

正确的解决方案是在responseSecondChartData / Fragment初始化的开始只调用一次Activity。例如:

fun onActivityCreated(...) {
    userModel.responseSecondChartData.observe(this,
            Observer {
                Log.e(TAG, "Second chart data: " + it.toString())
                Utils.debugger("FRAG ", "$it")
                secondChartData = it!!
                if (it.size > 0) {
                    splitSecondParentList(it!!)
                } else
                    Utils.showLongToast(requireActivity(), "No Data for Distribution")
            })
}

private fun hitSecondChartApi(country: String, category: String, market: String, weightKpi: String) {
    userModel.getResponseShareSecondChartData(country, category, market, weightKpi)
}

由于上面的代码仅创建了一个观察者,因此无需删除上面的观察者。