Retrofit 是 Android 最流行的网络请求库,与 Kotlin 协程和 Compose 完美配合。本文将深入讲解如何优雅地处理网络请求和状态管理。
一、UiState 密封类
sealed interface UiState<out T> {
data object Loading : UiState<Nothing>
data class Success<T>(val data: T) : UiState<T>
data class Error(val message: String) : UiState<Nothing>
}
二、安全 API 调用
suspend fun <T> safeApiCall(apiCall: suspend () -> T): Result<T> {
return try {
Result.Success(apiCall())
} catch (e: Exception) {
Result.Error(e)
}
}
三、ViewModel 实现
@HiltViewModel
class ArticleListViewModel @Inject constructor(
private val repository: ArticleRepository
) : ViewModel() {
private val _uiState = MutableStateFlow<UiState<List<Article>>>(UiState.Loading)
val uiState = _uiState.asStateFlow()
fun loadArticles() {
viewModelScope.launch {
_uiState.value = UiState.Loading
when (val result = repository.getArticles()) {
is Result.Success -> _uiState.value = UiState.Success(result.data)
is Result.Error -> _uiState.value = UiState.Error(result.exception.toUserMessage())
}
}
}
}
四、在 Compose 中处理状态
@Composable
fun ArticleListContent(uiState: UiState<List<Article>>) {
when (uiState) {
is UiState.Loading -> LoadingContent()
is UiState.Success -> ArticleList(uiState.data)
is UiState.Error -> ErrorContent(uiState.message)
}
}
五、最佳实践
- ✅ 使用密封类封装 UI 状态
- ✅ Repository 返回 Result 包装类
- ✅ 将异常转换为用户友好消息
- ✅ 处理 Loading、Success、Error 状态
- ✅ 实现下拉刷新
- ✅ 使用 Snackbar 显示非阻塞错误
总结
- UiState:统一管理加载状态
- Result:安全处理网络结果
- 错误处理:转换异常为用户消息
- 状态驱动 UI:根据状态显示内容