多次触发 Livedata 观察者

Livedata observers firing multiple times

我在为我的项目设置 MVVM 时遇到问题,一切似乎 运行 都很顺利,除了我注意到我的 LiveData 对象的观察者被多次调用。有时同一个 LiveData 对象更新一次 4-5 次。

主 activity 上托管了多个片段,所有片段都链接到连接到我的存储库的同一个 ViewModel,然后使用改造向我的服务器发出 API 请求。

然后我在每个片段中都有单独的观察者,从 ViewModel 观察同一个 LiveData 对象的变化,当使用单个片段时我没有对同一变化进行多次观察的问题但是在将项目分支到有很多片段我注意到观察者被称为很多。

我已经将观察者更改为全部使用 viewLifecycleOwner 无济于事。

这是一个片段示例,每个片段在观察 LiveData 的方式上基本相同,只是它们更新 UI 的不同部分。

override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        viewModel = ViewModelProviders.of(this, viewModelFactory)
                .get(WeatherViewModel::class.java)
        bindUI()
    }

    private fun bindUI() = launch {
        val currentWeatherResponse = viewModel.weatherResponse.await()

        currentWeatherResponse.observe(viewLifecycleOwner, Observer {
            if(it == null) return@Observer
            Log.i("CurrentWeatherFragment", "Observed")
            val currentWeather = it.currentWeather.first()
            updateTemperature(currentWeather.temperature, currentWeather.tempMin, currentWeather.tempMax)
            updateWind(currentWeather.windSpeed, currentWeather.windDirName)
            updateHumidity(currentWeather.humidity)

        })
    }

这是每个片段连接到的 ViewModel:

class WeatherViewModel(
        private val forecastRepository: IForecastRepository
) : ViewModel() {

    val weatherResponse by lazyDeferred {
        forecastRepository.getWeatherResponse()
    }

}

我存储库中的天气响应方法:

    override suspend fun getWeatherResponse(): LiveData<out DetailedPrediction> {
        return withContext(Dispatchers.IO) {
            initWeatherData()
            println("Get Weather response method")
            println(currentWeatherDao.getWeatherResponse().value)
            return@withContext currentWeatherDao.getWeatherResponse()
        }
    }

从 saveWeatherResponse 方法接收数据的天气 DAO:

    private val weatherResponse = MutableLiveData<DetailedPrediction>()
    private val radarImages = MutableLiveData<RadarImageList>()

    //TODO Return weather response from shared preferences
    override fun getWeatherResponse(): LiveData<DetailedPrediction> {
        return weatherResponse
    }

我希望能够从这个单一的 LiveData 事件中更新我所有的 UI 元素,它确实有效,但观察者触发了太多次,我终生无法我想知道为什么。

我不敢相信我花了这么长时间才找出一个简单的错误,但如果有人遇到这个问题(我怀疑)我是在每次观察时添加一个片段而不是替换片段,这意味着为每个片段创建了一个全新的观察者。

这是旧代码:


    fun addDailyWeatherFragment() {
        val fragmentTransaction: FragmentTransaction = fragmentManager!!.beginTransaction()
        val dailyWeatherFragment = DailyWeatherFragment()
        fragmentTransaction.add(R.id.fragmentContainer, dailyWeatherFragment)
        fragmentTransaction.commit()
    }

固定码:


    fun addDailyWeatherFragment() {
        val fragmentTransaction: FragmentTransaction = fragmentManager!!.beginTransaction()
        val dailyWeatherFragment = DailyWeatherFragment()
        fragmentTransaction.replace(R.id.fragmentContainer, dailyWeatherFragment)
        fragmentTransaction.commit()
    }