MVVM开源项目
https://github.com/wangjianxiandev/WanAndroidMvvm
https://gitee.com/jenly1314/AppTemplate
ResState
密封类是一个非常典型的网络请求状态封装,适用于大多数 MVVM 架构中的数据请求场景。它清晰地划分了三种核心状态:加载中(Loading)、成功(Success)、错误(Error),并且支持携带数据和错误信息。
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch
import java.io.IOException
import retrofit2.HttpException// 1. 数据模型:用户信息
data class User(val id: String,val name: String,val email: String,val avatarUrl: String
)// 2. 仓库层:封装数据来源(网络/本地)
class UserRepository {// 模拟网络请求:获取用户信息suspend fun getUserInfo(userId: String): User {// 实际项目中替换为Retrofit调用delay(1500) // 模拟网络延迟// 模拟不同场景return when (userId) {"valid_id" -> User(id = "valid_id",name = "张三",email = "zhangsan@example.com",avatarUrl = "https://example.com/avatar/zhangsan")"empty_data" -> throw IllegalArgumentException("用户数据为空") // 业务异常"network_error" -> throw IOException("网络连接超时") // 网络异常else -> throw HttpException(retrofit2.Response.error<Unit>(404, okhttp3.ResponseBody.create(null, ""))) // 接口异常}}
}// 3. ViewModel:处理业务逻辑与状态管理
class UserViewModel(private val repository: UserRepository = UserRepository() // 实际项目中通过依赖注入
) : ViewModel() {// 私有可变状态:仅内部修改private val _userState = MutableStateFlow<ResState<User>>(ResState.Loading)// 公开不可变状态:供View观察val userState: StateFlow<ResState<User>> = _userState.asStateFlow()// 加载用户信息(供View调用)fun fetchUserInfo(userId: String) {// 立即发送加载状态_userState.value = ResState.Loading// 在ViewModel作用域中启动协程viewModelScope.launch {try {// 调用仓库层获取数据val user = repository.getUserInfo(userId)// 发送成功状态(携带数据)_userState.value = ResState.Success(user)} catch (e: Exception) {// 根据异常类型设置错误状态val errorState = when (e) {is HttpException -> ResState.Error(errorCode = e.code(),errorMsg = "接口错误:${e.message() ?: "未知错误"}")is IOException -> ResState.Error(errorCode = -100,errorMsg = "网络异常:请检查网络连接")else -> ResState.Error(errorCode = -1,errorMsg = e.message ?: "未知错误")}_userState.value = errorState}}}// 重置状态(可选:用于刷新或返回初始状态)fun resetState() {_userState.value = ResState.Loading}
}// 4. 状态密封类(复用你定义的ResState)
sealed class ResState<out T> {data class Success<out T>(val data: T? = null) : ResState<T>()data class Error(var errorCode: Int = -1, var errorMsg: String = "") : ResState<Nothing>()object Loading : ResState<Nothing>()
}