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
}
}
浙公网安备 33010602011771号