下面给出一份 2024-07 最新、可直接落地的「网络请求框架」模板,全部基于 Kotlin 协程 + Flow + Retrofit + OkHttp,并遵循 MVVM + Repository 架构。你只需复制粘贴即可跑通业务。
1. 工程依赖(build.gradle.kts)
dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.8.1")
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.0")
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.8.0")
implementation("com.squareup.retrofit2:retrofit:2.11.0")
implementation("com.squareup.retrofit2:converter-gson:2.11.0")
implementation("com.squareup.okhttp3:okhttp:4.12.0")
implementation("com.squareup.okhttp3:logging-interceptor:4.12.0")
}
2. 数据层:Retrofit 接口 & 响应封装
// 1) 通用响应包装
sealed class ApiResult<out T> {
data class Success<out T>(val data: T) : ApiResult<T>()
data class Error(val exception: Throwable) : ApiResult<Nothing>()
}
// 2) 业务实体
data class User(val id: Int, val name: String)
// 3) Retrofit 接口
interface ApiService {
@GET("user/{id}")
suspend fun getUser(@Path("id") id: Int): User
}
3. 网络引擎单例
object NetworkModule {
private val okHttp = OkHttpClient.Builder()
.connectTimeout(15, TimeUnit.SECONDS)
.readTimeout(15, TimeUnit.SECONDS)
.addInterceptor(HttpLoggingInterceptor().apply {
level = HttpLoggingInterceptor.Level.BODY
})
.build()
val api: ApiService = Retrofit.Builder()
.baseUrl("https://api.example.com/")
.client(okHttp)
.addConverterFactory(GsonConverterFactory.create())
.build()
.create(ApiService::class.java)
}
4. Repository:把 挂起函数 封装成 Flow
class UserRepository(
private val api: ApiService = NetworkModule.api
) {
fun userFlow(id: Int): Flow<ApiResult<User>> = flow {
emit(ApiResult.Success(api.getUser(id))) // 网络请求
}
.flowOn(Dispatchers.IO) // 切换到 IO
.catch { e -> emit(ApiResult.Error(e)) } // 统一异常兜底
}
关键点:
flow {}保证冷流特性;flowOn(Dispatchers.IO)只影响上游;catch捕获下游异常。
5. ViewModel:UI 状态 = StateFlow
class UserViewModel(
private val repo: UserRepository = UserRepository()
) : ViewModel() {
private val _uiState = MutableStateFlow<ApiResult<User>?>(null)
val uiState: StateFlow<ApiResult<User>?> = _uiState
fun load(id: Int) {
repo.userFlow(id)
.onStart { _uiState.value = null } // 空状态/加载中
.onEach { _uiState.value = it } // 业务结果
.launchIn(viewModelScope) // 自动跟随生命周期
}
}
6. UI 层(以 Compose 为例)
@Composable
fun UserScreen(vm: UserViewModel = viewModel()) {
val state by vm.uiState.collectAsStateWithLifecycle()
when (val s = state) {
null -> CircularProgressIndicator()
is ApiResult.Success -> Text("Hi, ${s.data.name}!")
is ApiResult.Error -> Text("Error: ${s.exception.message}")
}
LaunchedEffect(Unit) { vm.load(1) }
}
若使用 View 体系,可替换成
repeatOnLifecycle(Lifecycle.State.STARTED)收集。
7. 进阶扩展(可选)
| 需求 | 方案 |
|---|---|
| 并发多个接口 | zip / combine |
| 分页 | Pager<Int, User> + Paging 3 |
| 缓存优先 | flow { emit(cache) } .combine(networkFlow) |
| 超时/重试 | .timeout(5.seconds) / .retry(3) |
8. 官方完整教程 & 源码
- Google Codelab(中文):
developer.android.com/codelabs/ko… - 掘金实战(含完整 Demo):
juejin.cn/post/737245… - 腾讯云(含缓存、异常处理):
cloud.tencent.com/developer/a…