Android 开发手册ANDROID DEV

CHAPTER 07客户端通信 · NETWORKING

网络层

App 大多是个"漂亮的网络客户端"。本章讲透 Retrofit、OkHttp 拦截器、Moshi/Kotlinx 序列化、缓存与超时重试策略。

开始阅读难度中级约2.5小时
07.1

网络层职责

集中管理请求构造、序列化、错误归一化、鉴权与缓存,不要在各处散落 URL 字符串。UI 只说"我要用户",拿到类型安全模型。

分层

传输层(OkHttp)→ 接口层(Retrofit 接口)→ 仓储层(Repository 转领域模型)。接口层用接口描述,便于 Mock。

07.2

Retrofit 基础

用注解声明 API,Retrofit 在运行期生成实现,天然兼容 Kotlin 挂起函数。

interface UserApi {
    @GET("users/{id}")
    suspend fun getUser(@Path("id") id: String): User
    @POST("users")
    suspend fun create(@Body user: User): User
}
val api = Retrofit.Builder()
    .baseUrl("https://api.example.com/")
    .addConverterFactory(MoshiConverterFactory.create())
    .build().create(UserApi::class.java)
07.3

序列化

Moshi(基于反射/codegen)或 kotlinx.serialization 把 JSON 映射到 Kotlin 数据类。注解处理字段名映射。

@Serializable
data class User(@SerialName("user_name") val userName: String, val id: Long)
默认值与稳定性

为字段提供默认值,避免服务端加字段导致解码失败崩溃;生产应 catch 解码异常并上报。

07.4

OkHttp 拦截器

拦截器统一注入鉴权头、日志、通用错误处理,业务接口保持干净。

val auth = Interceptor { chain ->
    val req = chain.request().newBuilder()
        .header("Authorization", "Bearer $token").build()
    chain.proceed(req)
}
OkHttpClient.Builder().addInterceptor(auth).build()
07.5

缓存与超时

用 Cache 减少重复请求,合理设置连接/读超时与重试,避免无限等待。

val client = OkHttpClient.Builder()
    .cache(Cache(File(cacheDir, "http"), 10L * 1024 * 1024))
    .connectTimeout(10, TimeUnit.SECONDS)
    .readTimeout(10, TimeUnit.SECONDS)
    .build()
07.6

错误处理

用密封类统一成功/失败,配合 Retrofit 的 HttpException 与 IOException 分类处理。

sealed interface Result<out T> { data class Ok<T>(val data: T): Result<T>; data class Err(val e: Throwable): Result<Nothing> }
07.7

Mock 与测试

让 Repository 依赖接口,测试时注入返回假数据的实现,业务测试不触网。

MockWebServer

需要验证真实 HTTP 行为时用 MockWebServer 在本地起假服务器,断言请求/响应。

07.8

常见陷阱

为什么请求偶发失败查不到原因?

错误常被吞掉:解码失败、非 2xx 没拦截、后台任务被回收。统一在网络层 catch 并归一化为业务错误。

主线程做网络会怎样?

Retrofit 的 suspend 接口已切到后台,但手动用 Call.execute() 在主线程会抛异常。始终走挂起或 enqueue。

07.9

实战练习

延伸资源