第2章 Retrofit基础配置与环境搭建
2.1 依赖引入与版本对齐
Retrofit基于OkHttp,需在build.gradle中同时声明核心库与序列化转换器。官方推荐使用com.squareup.retrofit2:retrofit配合对应Converter模块。
// app/build.gradle
dependencies {
// Retrofit 核心
implementation "com.squareup.retrofit2:retrofit:2.9.0"
// Gson 转换器
implementation "com.squareup.retrofit2:converter-gson:2.9.0"
// OkHttp(Retrofit自动依赖,建议显式声明版本)
implementation "com.squareup.okhttp3:okhttp:4.12.0"
// 日志拦截器(调试用)
implementation "com.squareup.okhttp3:logging-interceptor:4.12.0"
}
版本兼容说明:Retrofit 2.9.x 要求 OkHttp ≥ 3.12,Android minSdk ≥ 21。若项目已引入其他OkHttp版本,务必统一,避免类冲突。
2.2 BaseUrl设置与尾斜杠规则
BaseUrl是Retrofit实例的根路径,所有接口注解中的相对URL都会拼接在其后。关键约束:BaseUrl必须以/结尾,否则运行时抛出IllegalArgumentException。
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.example.com/") // 必须尾斜杠
.build();
若接口注解写了全路径,则BaseUrl被忽略;但推荐统一BaseUrl管理。生产环境通常将BaseUrl提取到配置类或BuildConfig中。
2.3 Converter/Gson集成
Converter负责将HTTP响应体(JSON)自动解析为Java/Kotlin对象,并序列化请求体。Gson是最常用的实现,集成只需一行代码:
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.example.com/")
.addConverterFactory(GsonConverterFactory.create())
.build();
原理:Retrofit在调用create(apiClass)时会为每个方法生成Call适配器,Converter在enqueue()或execute()时被触发,将OkHttp的ResponseBody转换为接口声明的返回类型。
| Converter | 适用场景 | 依赖坐标 |
|---|---|---|
| GsonConverterFactory | 标准JSON,团队熟悉Gson | converter-gson |
| JacksonConverterFactory | 需要注解驱动或性能更好 | converter-jackson |
| MoshiConverterFactory | Kotlin友好,空安全 | converter-moshi |
常见错误:忘记添加Converter工厂会导致
IllegalStateException: Unable to create call adapter for ...。另需确保Gson版本与Retrofit兼容(推荐Gson 2.10.x)。2.4 OkHttp拦截器基础
拦截器是OkHttp的钩子机制,可拦截请求/响应实现日志、重试、Header添加、缓存等。Retrofit允许通过OkHttpClient配置拦截器,然后传入Retrofit.Builder。
2.4.1 日志拦截器(HttpLoggingInterceptor)
HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor();
loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(loggingInterceptor)
.build();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.example.com/")
.client(client)
.addConverterFactory(GsonConverterFactory.create())
.build();
日志级别可选NONE、HEADERS、BODY。调试阶段使用BODY,生产环境需关闭或设置为HEADERS以防敏感数据泄露。
2.4.2 自定义拦截器(添加Header示例)
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(chain -> {
Request original = chain.request();
Request request = original.newBuilder()
.header("Authorization", "Bearer " + tokenProvider.getToken())
.header("Accept-Encoding", "gzip")
.build();
return chain.proceed(request);
})
.addInterceptor(loggingInterceptor)
.build();
拦截器执行顺序:自定义拦截器(应用拦截器)先于日志拦截器执行。若要统计请求耗时,建议在网络拦截器(
addNetworkInterceptor)中处理。2.5 环境验证与常见错误排查
完成配置后,编写一个简单API接口测试连通性:
public interface ApiService {
@GET("users")
Call> getUsers();
}
// 调用
ApiService service = retrofit.create(ApiService.class);
service.getUsers().enqueue(new Callback<List>() {
@Override public void onResponse(Call<List> call, Response<List> response) {
// 处理响应
}
@Override public void onFailure(Call<List> call, Throwable t) {
// 处理失败
}
});
常见错误与解决方案:
java.net.UnknownHostException:网络不可用或DNS解析失败,检查设备网络与BaseUrl拼写。java.net.SocketTimeoutException:连接或读取超时,在OkHttpClient中设置超时时间:connectTimeout(30, TimeUnit.SECONDS)。com.google.gson.JsonSyntaxException:JSON字段与Java实体不匹配,确保@SerializedName或字段名正确。java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING:类型声明错误,检查返回类型是对象还是字符串。
2.6 性能与稳定性优化建议
- 单例OkHttpClient:避免重复创建,利用其连接池复用机制。
- 合理设置超时:
connectTimeout、readTimeout、writeTimeout根据业务调整(默认10s)。 - 启用缓存:通过
Cache对象配合addNetworkInterceptor实现离线降级。 - 拦截器幂等:重试拦截器需配合
RetryInterceptor或OkHttp的retryOnConnectionFailure,避免非幂等请求重复提交。 - 日志分级:Debug构建使用
BODY,Release构建使用NONE或HEADERS,防止日志写入过多IO。
生产环境配置示例:将BaseUrl、超时时间、日志开关放入
buildConfig或gradle productFlavors中,通过BuildConfig.DEBUG动态切换。