Android Kotlin:View与ViewModel间用Flow实现可重试API请求的选型建议
用Flow实现View与ViewModel间的API请求重试方案
场景说明
基于整洁MVVM架构(Activity/Fragment → ViewModel → Repo → DataSource → Retrofit),项目全层使用Flow,需求是:
- 从View触发API请求
- 请求失败后,用户点击重试按钮可重新发起请求
- View与ViewModel间禁止使用LiveData/MutableLiveData,仅用Flow实现
现有代码问题
你当前的ViewModel代码每次调用fetchUserReviewData()都会创建新的Flow实例,View需要重新收集,且无法保留最新状态,重试时需要重新绑定,体验不佳。
推荐方案:使用MutableStateFlow
原因
- 状态持久化:MutableStateFlow始终持有最新的状态值,新订阅的View会立即收到当前最新状态(如加载中、成功、失败),无需等待重新请求。
- 重试逻辑简洁:点击重试按钮时,只需再次调用
fetchUserReviewData(),更新StateFlow的值即可,无需重新创建Flow实例。 - 生命周期友好:配合View的生命周期收集,能自动处理订阅与取消,避免内存泄漏。
修改后的ViewModel代码
import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.launch class YourViewModel(private val repository: YourRepository) : ViewModel() { // 私有可变StateFlow,用于内部更新状态 private val _userReviewData = MutableStateFlow<Resource<ReviewResponse>>(Resource.idle()) // 对外暴露不可变的StateFlow,供View订阅 val userReviewData: StateFlow<Resource<ReviewResponse>> = _userReviewData.asStateFlow() fun fetchUserReviewData() { // 先发送加载状态 _userReviewData.value = Resource.loading(true) // 在ViewModel的作用域内执行请求,自动跟随ViewModel生命周期销毁 viewModelScope.launch { repository.getUserReviewData().collect { resource -> _userReviewData.value = resource } } } }
View层订阅代码(Activity/Fragment)
import androidx.lifecycle.lifecycleScope import kotlinx.coroutines.flow.collect import kotlinx.coroutines.launch lifecycleScope.launch { // 仅在STARTED及以上生命周期状态时收集,确保生命周期安全 repeatOnLifecycle(Lifecycle.State.STARTED) { viewModel.userReviewData.collect { resource -> when (resource) { is Resource.Loading -> { // 显示加载进度框 } is Resource.Success -> { // 隐藏加载框,展示返回的数据 } is Resource.Error -> { // 隐藏加载框,显示错误提示和重试按钮 } } } } }
为什么不选其他Flow?
- 普通Flow:冷流,每次收集都会重新执行请求逻辑,且无法保留状态,重试时View需要重新绑定,体验差。
- SharedFlow/MutableSharedFlow:更适合一次性事件流(如Toast提示、页面导航),不适合需要持久化的状态管理,新订阅者不会收到历史状态。
内容的提问来源于stack exchange,提问作者Ishika Singh
相关产品推荐
相关产品推荐

