Kotlin StateFlow在repeatOnLifecycle中仅首次收集更新问题排查
问题原因与解决方案
核心问题
StateFlow 仅在新值与旧值不相等时才会触发收集逻辑。你的代码中存在两个关键问题导致后续更新不触发:
WeatherUIState中的weatherList使用了可变的ArrayList类型,这是引用类型- 更新状态时,你只是将同一个
ArrayList引用传递给了新的WeatherUIState对象,StateFlow 检测到前后值的引用未变,因此判定没有更新,不会发射新数据
修复步骤
1. 将 UI 状态改为不可变类型
UI 状态应该是不可变的,避免引用复用导致的状态检测失效。修改 WeatherUIState.kt:
data class WeatherUIState ( // 用不可变的 List 替代可变的 ArrayList val weatherList: List<WeatherData> = emptyList() )
2. 确保每次更新都生成新的列表实例
修改 WeatherViewModel.kt 中的 fetchWeather 方法,每次更新时创建新的 List 实例,让 StateFlow 能检测到状态变化:
fun fetchWeather(city: String) { Log.d("MY_TAG", "Updated uiState with $city") // 将原 ArrayList 转换为新的不可变 List 实例 _uiState.update { it.copy(weatherList = repository.weather.toList()) } }
额外说明
如果你之前尝试直接赋值(比如 _uiState.value = WeatherUIState(repository.weather)),问题仍然存在的原因是:repository.weather 是同一个 ArrayList 对象,前后两次 UIState 中的 weatherList 引用完全相同,StateFlow 会判定值未发生变化,因此不会触发收集逻辑。
内容的提问来源于stack exchange,提问作者Kind Warlock
相关产品推荐
相关产品推荐

