第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,团队熟悉Gsonconverter-gson
JacksonConverterFactory需要注解驱动或性能更好converter-jackson
MoshiConverterFactoryKotlin友好,空安全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:类型声明错误,检查返回类型是对象还是字符串。
Retrofit基础配置搭建流程图 1. 引入依赖 2. 创建OkHttpClient 3. 添加拦截器 4. baseUrl + Converter 5. retrofit.build() 6. create(ApiService) 7. enqueue/execute 关键说明:BaseUrl必须以"/"结尾;Converter不能省略;拦截器在OkHttpClient层配置, 多个拦截器按添加顺序执行。建议调试期使用HttpLoggingInterceptor.Level.BODY, 生产环境切换为HEADERS或关闭。自定义重试拦截器可提高弱网环境成功率。

2.6 性能与稳定性优化建议

  1. 单例OkHttpClient:避免重复创建,利用其连接池复用机制。
  2. 合理设置超时:connectTimeout、readTimeout、writeTimeout根据业务调整(默认10s)。
  3. 启用缓存:通过Cache对象配合addNetworkInterceptor实现离线降级。
  4. 拦截器幂等:重试拦截器需配合RetryInterceptor或OkHttp的retryOnConnectionFailure,避免非幂等请求重复提交。
  5. 日志分级:Debug构建使用BODY,Release构建使用NONE或HEADERS,防止日志写入过多IO。
生产环境配置示例:将BaseUrl、超时时间、日志开关放入buildConfig或gradle productFlavors中,通过BuildConfig.DEBUG动态切换。