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)
}
}
}

问题是,当我切换片段并回到这个片段时,它再次观察到最后一个状态,所以我得到了状态。成功然后状态。加载然后状态。成功触发。我试图使用Event和getContentIfNotHandled((来解决它?但这并没有改变任何事情。

第二个问题是我做得对吗,这是目前最好的方法吗?

一切如预期。返回片段后,您的LiveData仍然保持以前的成功状态,然后从存储库中获得另一个加载和成功。

对我来说,在存储库中设置loading状态似乎并不正确。我会将其移动到ViewModel,然后仅在必要时(如果您真的想在视图中显示它(才发出它,例如通过检查当前的liveData状态或在fetchFavourites方法中使用布尔标志。

至于第二个问题——一如既往——取决于情况。I、 个人不会为单个api调用创建流,而是宁愿使用suspend函数。

最新更新