android - Kotlin & flow & MVVM -> 切换片段时观察者多次触发
问题描述
我正在学习流程并在我的项目中实施它们,但我不确定我是否理解了所有内容。
这是我的模型
data class ResultResponse (
@field:Json(name = "count") val count : Int?,
@field:Json(name = "favorites") val "favorites") : List<Favorite>?
)
这是我的服务
@GET("...")
suspend fun getFavorites(@Path("visitor") visitor: String) : Response<ApiModel<ResultResponse>>
这是我的存储库
suspend fun getFavorites(visitor: String) = flow {
emit(apiCall { api.getFavorites(visitor) })
}.onStart {
emit(State.loading())
}
apiCall 在哪里
suspend fun <T> apiCall(call: suspend () -> Response<T>): State<T>
这是我的视图模型
private val parentJob = Job()
private val coroutineContext: CoroutineContext
get() = parentJob + Dispatchers.Default
private val scope = CoroutineScope(coroutineContext)
private val repository = FavoriteRepository(Api.favoriteService)
private val _favorites = MutableLiveData<State<ApiModel<ResultResponse>>>()
val favorites: LiveData<State<ApiModel<ResultResponse>>>
get() = _favorites
fun fetchFavorites() {
scope.launch {
repository.getFavorites(Preferences.visitor).collect {
_favorites.postValue(it)
}
}
}
这是我的片段
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
observer()
}
override fun onResume() {
super.onResume()
favoriteViewModel.fetchFavorites()
}
private fun observer() {
favoriteViewModel.favorites.observe(viewLifecycleOwner) { state ->
when (state) {
is State.Loading -> doSomethingOnLoadingState()
is State.Success -> doSomethingOnSuccessState(state)
is State.Error -> doSomethingOnErrorState(state)
}
}
}
问题是当我切换片段并回到这个片段时,它再次观察到最后一个状态,所以我得到了 State.Success 然后 State.Loading 然后 State.Success 触发。我尝试使用事件和 getContentIfNotHandled() 来解决它?但它没有改变任何东西。
第二个问题是我做对了吗,这是目前最好的方法吗?
解决方案
一切都按预期工作。返回片段后,您的 LiveData 仍保持先前的 Success 状态,然后从存储库中获取另一个 Loading 和 Success。
对我来说,loading
在你的存储库中有一个状态似乎是不对的。我会将其移至 ViewModel,然后仅在必要时发出它(如果您确实想在视图中显示它),例如通过检查当前 liveData 状态或在 fetchFavourites 方法中使用布尔标志。
至于第二个问题 - 一如既往 - 这取决于。我个人不会为单个 api 调用创建流程,而是更愿意使用挂起函数。
推荐阅读
- jmeter - 在 Jmeter 中获得第一组循环的响应后,如何发送第二组循环
- c# - Itextsharp 5.5 splitLate 正在扩展 lastrow
- openid-connect - 可以用标准的 google 请求替换 google plus open ID 请求吗?
- java - 使用 WebTestClient 在 springBootTest 中禁用安全性
- php - 在 pre_get_posts 中更改查询后修复 found_posts - WordPress
- typescript - 有没有办法从可以返回多个的函数中返回特定类型?
- css - 具有缩放样式属性的 div 中的 Openlayers
- reactjs - 无法组合 withStyle、withWidth 和 injectIntl
- java - Spring boot mongo 数据查找存储库在有 hatos 时返回 Unsupported operation 错误
- microsoft-graph-api - 发出邀请时收到 403