Retrofit+OkHttp为什么要一起使用?

Retrofit+OkHttp是网络编程中的黄金搭档,因为他俩分层明确,职责清晰

OkHttp 是底层网络引擎,基于Http/2he Http/1.1,
支持连接池,请求缓存,数据压缩,网络拦截和证书校验
当然也支持超时跟重连。

Retrofit 是上层接口封装,将Http的api封装成接口,
请求响应的数据序列化,
也支持线程的调度和协程。

Retrofit 职责:
1.定义api接口,把请求参数序列化(@Query,@Body)
2.把响应数据反序列化
3.协程,回调适配。

OKhttp的职责:
1.实际的Http请求发送
2.连接池管理
3.拦截和认证
4.SSL/TLS安全

添加拦截器,认证和加密信息,包括证书锁定,请求加密,签名等。
fun createSecureOkHttpClient(): OkHttpClient {
return OkHttpClient.Builder()
.addInterceptor(SslPinningInterceptor()) // SSL证书锁定
.addInterceptor(EncryptionInterceptor()) // 请求加密
.addInterceptor(SignatureInterceptor()) // 请求签名
.certificatePinner( // 证书锁定
CertificatePinner.Builder()
.add("api.bank.com", "sha256/AAAAAAAAAAAAAAAAAAAAAAAA=")
.build()
)
.build()
}

这是一个完整的请求模型:

// 1. 数据模型
data class User(
val id: Int,
val name: String,
val email: String
)

data class LoginRequest(
val username: String,
val password: String
)

data class LoginResponse(
val token: String,
val user: User
)

// 2. 定义 API 接口(Retrofit)
interface ApiService {

// 登录接口
@POST("auth/login")
suspend fun login(@Body request: LoginRequest): LoginResponse

// 获取用户信息
@GET("users/{id}")
suspend fun getUser(@Path("id") userId: Int): User

// 查询用户列表
@GET("users")
suspend fun getUsers(
@Query("page") page: Int = 1,
@Query("limit") limit: Int = 20
): List

// 上传文件(Multipart)
@Multipart
@POST("upload")
suspend fun uploadAvatar(
@Part file: MultipartBody.Part,
@Part("description") description: RequestBody
): Response
}

// 3. 自定义拦截器
class AuthInterceptor(private val token: String?) : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
val originalRequest = chain.request()

val requestBuilder = originalRequest.newBuilder()
.addHeader("User-Agent", "MyApp/1.0")

// 添加认证头
token?.let {
requestBuilder.addHeader("Authorization", "Bearer $it")
}

val request = requestBuilder.build()
return chain.proceed(request)
}
}

// 4. 网络客户端构建器
object NetworkClient {

// 创建 OkHttpClient
private fun createOkHttpClient(): OkHttpClient {
return OkHttpClient.Builder()
.connectTimeout(30, TimeUnit.SECONDS) // 连接超时
.readTimeout(30, TimeUnit.SECONDS) // 读取超时
.writeTimeout(30, TimeUnit.SECONDS) // 写入超时
.addInterceptor(AuthInterceptor(getTokenFromStorage())) // 认证拦截器
.addInterceptor(HttpLoggingInterceptor().apply {
level = HttpLoggingInterceptor.Level.BODY // 日志级别
})
.addInterceptor { chain ->
// 通用请求拦截器
val request = chain.request()
val response = chain.proceed(request)

// 全局错误处理
if (!response.isSuccessful) {
// 可以根据状态码做统一处理
when (response.code) {
401 -> { /* Token 过期,跳转登录 / }
403 -> { /
无权限 / }
500 -> { /
服务器错误 */ }
}
}
response
}
.addInterceptor { chain ->
// 重试拦截器
var retryCount = 0
var response: Response
var request = chain.request()

while (true) {
try {
response = chain.proceed(request)
if (response.isSuccessful || retryCount >= 3) {
return@addInterceptor response
}
} catch (e: IOException) {
if (retryCount >= 3) throw e
}

retryCount++
// 指数退避
Thread.sleep((1000 * Math.pow(2.0, retryCount.toDouble())).toLong())
}

chain.proceed(request)
}
.build()
}

// 创建 Retrofit 实例
private val retrofit: Retrofit by lazy {
Retrofit.Builder()
.baseUrl("https://api.example.com/") // 基础URL
.client(createOkHttpClient()) // 注入 OkHttpClient
.addConverterFactory(GsonConverterFactory.create()) // JSON转换
.build()
}

// 创建 API 服务
val apiService: ApiService by lazy {
retrofit.create(ApiService::class.java)
}

// 模拟从存储中获取token
private fun getTokenFromStorage(): String? {
// 实际从 SharedPreferences 或 DataStore 读取
return "fake_jwt_token_123456"
}
}

// 5. Repository 层(数据访问)
class UserRepository {
private val apiService = NetworkClient.apiService

suspend fun login(username: String, password: String): Result {
return try {
val response = apiService.login(LoginRequest(username, password))
Result.success(response)
} catch (e: Exception) {
Result.failure(e)
}
}

suspend fun getUser(userId: Int): Result {
return try {
val user = apiService.getUser(userId)
Result.success(user)
} catch (e: Exception) {
Result.failure(e)
}
}

suspend fun getUsers(page: Int = 1): Result<List> {
return try {
val users = apiService.getUsers(page)
Result.success(users)
} catch (e: Exception) {
Result.failure(e)
}
}
}

// 6. ViewModel 层

fun loadUsers(page: Int = 1) {
viewModelScope.launch {
_loading.value = true
val result = repository.getUsers(page)
_loading.value = false

result.onSuccess { users ->
_users.value = users
}.onFailure { error ->
showError(error.message ?: "加载失败")
}
}
}

}

// 8. 自定义 CallAdapter(RxJava 支持示例)
// 如果需要支持 RxJava
/*
class RxJavaCallAdapterFactory : CallAdapter.Factory() {
override fun get(
returnType: Type,
annotations: Array,
retrofit: Retrofit
): CallAdapter<*, *>? {
// 实现 RxJava 适配器
return null
}
}

posted @ 2026-05-27 10:50  僧cz0727  阅读(8)  评论(0)    收藏  举报