Retrofit:优雅的JAVA网络请求框架实战
本文深入讲解Square公司开源的Retrofit框架,从架构设计到实战应用,帮助你快速掌握这个强大的网络请求工具。
1. 引言:为什么选择Retrofit
在JAVA开发中,网络请求是绝大多数应用的核心功能。传统的HttpURLConnection或Apache HttpClient使用繁琐,代码冗余。Retrofit由Square公司开源,它将RESTful API转化为Java接口,极大地简化了网络请求的编写。
1.1 Retrofit的核心优势
- 声明式API定义 - 使用注解定义接口,代码简洁清晰
- 自动序列化 - 内置Gson、Jackson等转换器,自动处理JSON
- OkHttp集成 - 底层基于OkHttp,性能强大且稳定
- 灵活的CallAdapter - 支持RxJava、协程等异步框架
- 易于测试 - 接口化设计,便于Mock和单元测试
1.2 与其他框架的对比
| 特性 | Retrofit | OkHttp |
|---|---|---|
| API设计 | 声明式接口 | 原始API |
| 学习曲线 | 低 | 高 |
| 扩展性 | 优秀 | 优秀 |
| 异步支持 | 多种方式 | 回调 |
2. 核心架构解析
Retrofit采用分层架构设计,每一层职责清晰,协同工作完成网络请求。

2.1 架构层次
应用层(Application Layer)
- 定义API接口
- 调用网络请求方法
- 处理响应结果
Retrofit核心层
- 动态代理拦截方法调用
- 注解解析(@GET、@POST等)
- 请求参数组装
- 响应数据转换
OkHttp网络层
- HTTP连接管理
- 请求/响应拦截器链
- 缓存策略
- 连接池复用
网络传输层
- TCP/IP协议通信
- TLS/SSL加密
- DNS解析
2.2 核心组件
java
// 1. ServiceMethod - 封装接口方法的所有信息
class ServiceMethod<T> {
private final okhttp3.Call.Factory callFactory;
private final CallAdapter<T, ?> callAdapter;
private final Converter<ResponseBody, T> responseConverter;
// ...解析注解、构建请求
}
// 2. CallAdapter - 适配不同的异步框架
interface CallAdapter<R, T> {
Type responseType();
T adapt(Call<R> call);
}
// 3. Converter - 数据转换器
interface Converter<F, T> {
T convert(F value) throws IOException;
}
// 4. Interceptor - 请求/响应拦截器
interface Interceptor {
Response intercept(Chain chain) throws IOException;
}
3. 快速上手:基础用法
3.1 添加依赖
首先在build.gradle中添加依赖:
arduino
dependencies {
// Retrofit核心库
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
// Gson转换器(用于JSON解析)
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
// RxJava适配器(可选)
implementation 'com.squareup.retrofit2:adapter-rxjava3:2.9.0'
// OkHttp日志拦截器(调试用)
implementation 'com.squareup.okhttp3:logging-interceptor:4.10.0'
}
3.2 定义数据模型
typescript
// 用户实体类
public class User {
private int id;
private String name;
private String email;
private String avatar;
// Getter和Setter方法
public int getId() { return id; }
public void setId(int id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getEmail() { return email; }
public void setEmail(String email) { this.email = email; }
public String getAvatar() { return avatar; }
public void setAvatar(String avatar) { this.avatar = avatar; }
}
// API响应包装类
public class ApiResponse<T> {
private int code;
private String message;
private T data;
public boolean isSuccess() {
return code == 200;
}
// Getter和Setter
public int getCode() { return code; }
public String getMessage() { return message; }
public T getData() { return data; }
}
3.3 定义API接口

less
public interface UserService {
// GET请求 - 查询用户信息
@GET("users/{id}")
Call<ApiResponse<User>> getUser(@Path("id") int userId);
// POST请求 - 创建用户
@POST("users")
Call<ApiResponse<User>> createUser(@Body User user);
// 带查询参数的GET请求
@GET("users")
Call<ApiResponse<List<User>>> listUsers(
@Query("page") int page,
@Query("size") int pageSize
);
// 带Header的请求
@Headers("Content-Type: application/json")
@GET("users/profile")
Call<ApiResponse<User>> getProfile(
@Header("Authorization") String token
);
// 文件上传
@Multipart
@POST("upload/avatar")
Call<ApiResponse<String>> uploadAvatar(
@Part MultipartBody.Part file,
@Part("userId") RequestBody userId
);
// 表单提交
@FormUrlEncoded
@POST("login")
Call<ApiResponse<String>> login(
@Field("username") String username,
@Field("password") String password
);
}
3.4 创建Retrofit实例
typescript
public class RetrofitClient {
private static final String BASE_URL = "https://api.example.com/";
private static Retrofit retrofit;
// 单例模式获取Retrofit实例
public static Retrofit getInstance() {
if (retrofit == null) {
synchronized (RetrofitClient.class) {
if (retrofit == null) {
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.client(getOkHttpClient())
.addConverterFactory(GsonConverterFactory.create())
.build();
}
}
}
return retrofit;
}
// 配置OkHttpClient
private static OkHttpClient getOkHttpClient() {
return new OkHttpClient.Builder()
.connectTimeout(30, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.writeTimeout(30, TimeUnit.SECONDS)
.build();
}
// 获取API服务
public static <T> T createService(Class<T> serviceClass) {
return getInstance().create(serviceClass);
}
}
3.5 发起网络请求
java
public class UserRepository {
private final UserService userService;
public UserRepository() {
userService = RetrofitClient.createService(UserService.class);
}
// 同步请求(不推荐在主线程使用)
public User getUserSync(int userId) {
try {
Response<ApiResponse<User>> response =
userService.getUser(userId).execute();
if (response.isSuccessful() && response.body() != null) {
ApiResponse<User> apiResponse = response.body();
if (apiResponse.isSuccess()) {
return apiResponse.getData();
}
}
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
// 异步请求(推荐)
public void getUserAsync(int userId, final Callback<User> callback) {
userService.getUser(userId).enqueue(new Callback<ApiResponse<User>>() {
@Override
public void onResponse(Call<ApiResponse<User>> call,
Response<ApiResponse<User>> response) {
if (response.isSuccessful() && response.body() != null) {
ApiResponse<User> apiResponse = response.body();
if (apiResponse.isSuccess()) {
callback.onSuccess(apiResponse.getData());
return;
}
}
callback.onError(new Exception("请求失败"));
}
@Override
public void onFailure(Call<ApiResponse<User>> call, Throwable t) {
callback.onError(t);
}
});
}
// 自定义回调接口
public interface Callback<T> {
void onSuccess(T data);
void onError(Throwable error);
}
}
4. 深入理解:请求执行流程

4.1 流程详解
当我们调用API接口方法时,Retrofit内部经历了以下7个步骤:
步骤1:调用API方法
ini
Call<ApiResponse<User>> call = userService.getUser(100);
步骤2:动态代理拦截
Retrofit使用Java的动态代理机制,拦截接口方法调用:
typescript
// Retrofit内部实现
public <T> T create(final Class<T> service) {
return (T) Proxy.newProxyInstance(
service.getClassLoader(),
new Class<?>[] { service },
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) {
// 拦截方法调用
ServiceMethod<?> serviceMethod = loadServiceMethod(method);
return serviceMethod.invoke(args);
}
}
);
}
步骤3:解析方法注解
ini
// 解析@GET、@POST、@Path、@Query等注解
ServiceMethod<?> serviceMethod = new ServiceMethod.Builder<>(retrofit, method)
.build();
// 提取请求信息
String httpMethod = "GET";
String relativeUrl = "users/{id}";
Map<String, String> pathParams = new HashMap<>();
pathParams.put("id", "100");
步骤4:构建OkHttp请求
vbscript
// 组装Request对象
Request request = new Request.Builder()
.url("https://api.example.com/users/100")
.method("GET", null)
.build();
// 创建OkHttp Call
okhttp3.Call okHttpCall = okHttpClient.newCall(request);
步骤5:执行网络请求
less
// 同步执行
Response response = okHttpCall.execute();
// 或异步执行
okHttpCall.enqueue(new okhttp3.Callback() {
@Override
public void onResponse(okhttp3.Call call, Response response) {
// 处理响应
}
@Override
public void onFailure(okhttp3.Call call, IOException e) {
// 处理失败
}
});
步骤6:响应数据转换
ini
// 使用Converter将ResponseBody转换为Java对象
Converter<ResponseBody, ApiResponse<User>> converter =
retrofit.responseBodyConverter(type, annotations);
ApiResponse<User> result = converter.convert(response.body());
步骤7:返回结果对象
swift
// 通过CallAdapter包装返回结果
CallAdapter<ApiResponse<User>, Call<ApiResponse<User>>> callAdapter =
retrofit.callAdapter(returnType, annotations);
return callAdapter.adapt(new OkHttpCall<>(serviceMethod, args));
4.2 源码分析:动态代理的妙用
kotlin
// Retrofit核心方法
final class Retrofit {
public <T> T create(final Class<T> service) {
validateServiceInterface(service);
return (T) Proxy.newProxyInstance(
service.getClassLoader(),
new Class<?>[] { service },
new InvocationHandler() {
private final Platform platform = Platform.get();
private final Object[] emptyArgs = new Object[0];
@Override
public @Nullable Object invoke(Object proxy, Method method,
@Nullable Object[] args) throws Throwable {
// 如果是Object的方法,直接调用
if (method.getDeclaringClass() == Object.class) {
return method.invoke(this, args);
}
// 如果是默认方法(Java 8+),使用默认实现
if (platform.isDefaultMethod(method)) {
return platform.invokeDefaultMethod(method, service, proxy, args);
}
// 核心:加载并执行ServiceMethod
return loadServiceMethod(method).invoke(args != null ? args : emptyArgs);
}
}
);
}
// 缓存ServiceMethod,避免重复解析
ServiceMethod<?> loadServiceMethod(Method method) {
ServiceMethod<?> result = serviceMethodCache.get(method);
if (result != null) return result;
synchronized (serviceMethodCache) {
result = serviceMethodCache.get(method);
if (result == null) {
result = ServiceMethod.parseAnnotations(this, method);
serviceMethodCache.put(method, result);
}
}
return result;
}
}
5. 高级特性:拦截器与转换器
5.1 拦截器链机制

拦截器(Interceptor)是OkHttp的核心机制,Retrofit继承了这一强大功能。拦截器分为两类:
应用拦截器(Application Interceptor)
- 在请求发送前和响应返回后执行
- 可以修改请求头、请求体
- 可以记录日志、统计耗时
网络拦截器(Network Interceptor)
- 在网络请求时执行
- 可以访问连接信息
- 可以处理重定向、缓存
5.1.1 自定义Token拦截器
java
public class TokenInterceptor implements Interceptor {
private String token;
public TokenInterceptor(String token) {
this.token = token;
}
@Override
public Response intercept(Chain chain) throws IOException {
Request originalRequest = chain.request();
// 如果已有Authorization头,不做处理
if (originalRequest.header("Authorization") != null) {
return chain.proceed(originalRequest);
}
// 添加Token到请求头
Request newRequest = originalRequest.newBuilder()
.header("Authorization", "Bearer " + token)
.build();
return chain.proceed(newRequest);
}
}
5.1.2 日志拦截器
ini
public class LoggingInterceptor implements Interceptor {
private static final String TAG = "OkHttp";
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
// 记录请求信息
long startTime = System.nanoTime();
Log.d(TAG, String.format("发送请求: %s %s",
request.method(), request.url()));
// 记录请求头
Headers headers = request.headers();
for (int i = 0; i < headers.size(); i++) {
Log.d(TAG, headers.name(i) + ": " + headers.value(i));
}
// 执行请求
Response response = chain.proceed(request);
// 记录响应信息
long endTime = System.nanoTime();
double duration = (endTime - startTime) / 1e6d;
Log.d(TAG, String.format("收到响应: %d %s (耗时%.1fms)",
response.code(), response.request().url(), duration));
return response;
}
}
5.1.3 错误重试拦截器
java
public class RetryInterceptor implements Interceptor {
private int maxRetry = 3; // 最大重试次数
private long retryDelay = 1000; // 重试延迟(毫秒)
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
Response response = null;
IOException exception = null;
for (int i = 0; i <= maxRetry; i++) {
try {
response = chain.proceed(request);
// 如果响应成功,直接返回
if (response.isSuccessful()) {
return response;
}
// 关闭响应体
if (response != null) {
response.close();
}
} catch (IOException e) {
exception = e;
Log.w("RetryInterceptor", "请求失败,尝试重试 " + (i + 1) + "/" + maxRetry);
}
// 如果不是最后一次重试,等待后再试
if (i < maxRetry) {
try {
Thread.sleep(retryDelay);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new IOException("重试被中断", e);
}
}
}
// 所有重试都失败,抛出异常
if (exception != null) {
throw exception;
}
return response;
}
}
5.1.4 配置拦截器
scss
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(new TokenInterceptor("your_token_here"))
.addInterceptor(new LoggingInterceptor())
.addInterceptor(new RetryInterceptor())
.connectTimeout(30, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.build();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.example.com/")
.client(client)
.addConverterFactory(GsonConverterFactory.create())
.build();
5.2 数据转换器(Converter)
Retrofit支持多种数据转换器,用于序列化和反序列化:
5.2.1 Gson转换器(最常用)
java
// 添加依赖
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
// 自定义Gson配置
Gson gson = new GsonBuilder()
.setDateFormat("yyyy-MM-dd HH:mm:ss")
.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
.create();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create(gson))
.build();
5.2.2 Jackson转换器
ini
// 添加依赖
implementation 'com.squareup.retrofit2:converter-jackson:2.9.0'
// 自定义ObjectMapper
ObjectMapper mapper = new ObjectMapper();
mapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(JacksonConverterFactory.create(mapper))
.build();
5.2.3 自定义转换器
scala
public class CustomResponseConverter implements Converter<ResponseBody, ApiResponse<?>> {
private final Gson gson;
private final Type type;
public CustomResponseConverter(Gson gson, Type type) {
this.gson = gson;
this.type = type;
}
@Override
public ApiResponse<?> convert(ResponseBody value) throws IOException {
String json = value.string();
try {
// 先解析为通用响应
JsonObject jsonObject = JsonParser.parseString(json).getAsJsonObject();
// 检查响应码
int code = jsonObject.get("code").getAsInt();
String message = jsonObject.get("message").getAsString();
// 如果失败,返回错误信息
if (code != 200) {
ApiResponse<?> errorResponse = new ApiResponse<>();
errorResponse.setCode(code);
errorResponse.setMessage(message);
return errorResponse;
}
// 成功,解析data字段
return gson.fromJson(json, type);
} finally {
value.close();
}
}
}
// 自定义Converter.Factory
public class CustomConverterFactory extends Converter.Factory {
private final Gson gson;
public CustomConverterFactory(Gson gson) {
this.gson = gson;
}
@Override
public Converter<ResponseBody, ?> responseBodyConverter(
Type type, Annotation[] annotations, Retrofit retrofit) {
return new CustomResponseConverter(gson, type);
}
}
5.3 CallAdapter(调用适配器)
CallAdapter用于适配不同的异步框架:
5.3.1 RxJava3适配器
less
// 添加依赖
implementation 'com.squareup.retrofit2:adapter-rxjava3:2.9.0'
// 配置Retrofit
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addCallAdapterFactory(RxJava3CallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.build();
// 定义返回Observable的API
public interface UserService {
@GET("users/{id}")
Observable<ApiResponse<User>> getUser(@Path("id") int userId);
@GET("users")
Single<ApiResponse<List<User>>> listUsers();
@POST("users")
Completable createUser(@Body User user);
}
// 使用RxJava
userService.getUser(100)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
response -> {
// 成功处理
if (response.isSuccess()) {
User user = response.getData();
// 更新UI
}
},
error -> {
// 错误处理
Log.e("Error", "请求失败", error);
}
);
5.3.2 Kotlin协程适配器
kotlin
// Kotlin代码示例
// 添加依赖
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4'
// 定义suspend函数API
interface UserService {
@GET("users/{id}")
suspend fun getUser(@Path("id") userId: Int): ApiResponse<User>
}
// 在协程中调用
viewModelScope.launch {
try {
val response = userService.getUser(100)
if (response.isSuccess) {
val user = response.data
// 更新UI
}
} catch (e: Exception) {
// 错误处理
}
}
6. 实战应用:生产级配置

6.1 完整的Retrofit配置
csharp
public class NetworkModule {
private static final String BASE_URL = "https://api.example.com/";
private static final int TIMEOUT = 30; // 秒
// 单例Retrofit实例
private static volatile Retrofit retrofit;
public static Retrofit provideRetrofit() {
if (retrofit == null) {
synchronized (NetworkModule.class) {
if (retrofit == null) {
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.client(provideOkHttpClient())
.addConverterFactory(provideGsonConverterFactory())
.addCallAdapterFactory(RxJava3CallAdapterFactory.create())
.build();
}
}
}
return retrofit;
}
// 配置OkHttpClient
private static OkHttpClient provideOkHttpClient() {
return new OkHttpClient.Builder()
// 超时配置
.connectTimeout(TIMEOUT, TimeUnit.SECONDS)
.readTimeout(TIMEOUT, TimeUnit.SECONDS)
.writeTimeout(TIMEOUT, TimeUnit.SECONDS)
// 连接池配置
.connectionPool(new ConnectionPool(5, 5, TimeUnit.MINUTES))
// SSL证书信任(生产环境慎用)
.hostnameVerifier((hostname, session) -> true)
// 拦截器配置
.addInterceptor(provideHeaderInterceptor())
.addInterceptor(provideLoggingInterceptor())
.addInterceptor(provideRetryInterceptor())
// 缓存配置
.cache(provideCache())
.build();
}
// Header拦截器
private static Interceptor provideHeaderInterceptor() {
return chain -> {
Request original = chain.request();
Request request = original.newBuilder()
.header("Content-Type", "application/json")
.header("Accept", "application/json")
.header("User-Agent", "Android App/1.0")
.header("Authorization", "Bearer " + getToken())
.method(original.method(), original.body())
.build();
return chain.proceed(request);
};
}
// 日志拦截器
private static Interceptor provideLoggingInterceptor() {
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
logging.setLevel(BuildConfig.DEBUG
? HttpLoggingInterceptor.Level.BODY
: HttpLoggingInterceptor.Level.NONE);
return logging;
}
// 重试拦截器
private static Interceptor provideRetryInterceptor() {
return new RetryInterceptor();
}
// 缓存配置
private static Cache provideCache() {
File cacheDir = new File(getApplication().getCacheDir(), "http_cache");
int cacheSize = 10 * 1024 * 1024; // 10MB
return new Cache(cacheDir, cacheSize);
}
// Gson配置
private static GsonConverterFactory provideGsonConverterFactory() {
Gson gson = new GsonBuilder()
.setDateFormat("yyyy-MM-dd HH:mm:ss")
.setLenient()
.create();
return GsonConverterFactory.create(gson);
}
// 获取Token(示例)
private static String getToken() {
// 从SharedPreferences或其他地方获取token
return "your_token_here";
}
private static Application getApplication() {
// 获取Application实例
return MyApplication.getInstance();
}
}
6.2 统一错误处理
java
public class ApiException extends Exception {
private int code;
private String msg;
public ApiException(int code, String msg) {
super(msg);
this.code = code;
this.msg = msg;
}
// 错误码定义
public static final int NETWORK_ERROR = -1;
public static final int PARSE_ERROR = -2;
public static final int UNKNOWN_ERROR = -3;
public static final int AUTH_ERROR = 401;
public static final int SERVER_ERROR = 500;
// Getter
public int getCode() { return code; }
public String getMsg() { return msg; }
}
// 统一的响应处理器
public abstract class ApiCallback<T> implements Callback<ApiResponse<T>> {
@Override
public void onResponse(Call<ApiResponse<T>> call, Response<ApiResponse<T>> response) {
if (response.isSuccessful()) {
ApiResponse<T> body = response.body();
if (body != null && body.isSuccess()) {
onSuccess(body.getData());
} else {
onFailure(new ApiException(
body != null ? body.getCode() : ApiException.UNKNOWN_ERROR,
body != null ? body.getMessage() : "未知错误"
));
}
} else {
onFailure(new ApiException(
response.code(),
"HTTP错误: " + response.code()
));
}
}
@Override
public void onFailure(Call<ApiResponse<T>> call, Throwable t) {
if (t instanceof IOException) {
onFailure(new ApiException(ApiException.NETWORK_ERROR, "网络连接失败"));
} else if (t instanceof JsonSyntaxException) {
onFailure(new ApiException(ApiException.PARSE_ERROR, "数据解析失败"));
} else {
onFailure(new ApiException(ApiException.UNKNOWN_ERROR, t.getMessage()));
}
}
protected abstract void onSuccess(T data);
protected abstract void onFailure(ApiException e);
}
// 使用示例
userService.getUser(100).enqueue(new ApiCallback<User>() {
@Override
protected void onSuccess(User user) {
// 处理成功结果
textView.setText(user.getName());
}
@Override
protected void onFailure(ApiException e) {
// 统一错误处理
Toast.makeText(context, e.getMsg(), Toast.LENGTH_SHORT).show();
}
});
6.3 多BaseUrl支持
在实际项目中,可能需要访问多个不同的API服务器:
less
public class MultiBaseUrlInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
HttpUrl oldUrl = request.url();
// 从请求头中获取自定义的BaseUrl标识
String baseUrlName = request.header("BaseUrl");
if (baseUrlName != null) {
// 移除请求头
request = request.newBuilder()
.removeHeader("BaseUrl")
.build();
// 根据标识替换BaseUrl
HttpUrl newBaseUrl = getBaseUrl(baseUrlName);
if (newBaseUrl != null) {
HttpUrl newUrl = oldUrl.newBuilder()
.scheme(newBaseUrl.scheme())
.host(newBaseUrl.host())
.port(newBaseUrl.port())
.build();
request = request.newBuilder()
.url(newUrl)
.build();
}
}
return chain.proceed(request);
}
private HttpUrl getBaseUrl(String name) {
switch (name) {
case "API_SERVER":
return HttpUrl.parse("https://api.example.com/");
case "IMAGE_SERVER":
return HttpUrl.parse("https://img.example.com/");
case "FILE_SERVER":
return HttpUrl.parse("https://file.example.com/");
default:
return null;
}
}
}
// API接口定义
public interface FileService {
@Headers("BaseUrl: FILE_SERVER")
@Multipart
@POST("upload")
Call<ApiResponse<String>> uploadFile(@Part MultipartBody.Part file);
}
6.4 请求取消
typescript
public class RequestManager {
private final Map<String, Call<?>> callMap = new ConcurrentHashMap<>();
// 添加请求
public void addCall(String tag, Call<?> call) {
callMap.put(tag, call);
}
// 取消指定请求
public void cancelCall(String tag) {
Call<?> call = callMap.remove(tag);
if (call != null && !call.isCanceled()) {
call.cancel();
}
}
// 取消所有请求
public void cancelAll() {
for (Call<?> call : callMap.values()) {
if (!call.isCanceled()) {
call.cancel();
}
}
callMap.clear();
}
}
// Activity中使用
public class UserActivity extends AppCompatActivity {
private RequestManager requestManager = new RequestManager();
private void loadUser(int userId) {
Call<ApiResponse<User>> call = userService.getUser(userId);
requestManager.addCall("loadUser", call);
call.enqueue(new ApiCallback<User>() {
@Override
protected void onSuccess(User user) {
// 处理结果
}
@Override
protected void onFailure(ApiException e) {
// 处理错误
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
// Activity销毁时取消所有请求
requestManager.cancelAll();
}
}
7. 最佳实践

7.1 单例模式管理Retrofit
❌ 错误做法:
java
// 每次都创建新实例,浪费资源
public User getUser(int id) {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.example.com/")
.addConverterFactory(GsonConverterFactory.create())
.build();
UserService service = retrofit.create(UserService.class);
// ...
}
✅ 正确做法:
csharp
// 使用单例模式,全局共享
public class ApiClient {
private static volatile ApiClient instance;
private final Retrofit retrofit;
private ApiClient() {
retrofit = new Retrofit.Builder()
.baseUrl("https://api.example.com/")
.client(createOkHttpClient())
.addConverterFactory(GsonConverterFactory.create())
.build();
}
public static ApiClient getInstance() {
if (instance == null) {
synchronized (ApiClient.class) {
if (instance == null) {
instance = new ApiClient();
}
}
}
return instance;
}
public <T> T createService(Class<T> serviceClass) {
return retrofit.create(serviceClass);
}
}
7.2 合理配置超时时间
scss
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(10, TimeUnit.SECONDS) // 连接超时
.readTimeout(30, TimeUnit.SECONDS) // 读取超时
.writeTimeout(30, TimeUnit.SECONDS) // 写入超时
.callTimeout(60, TimeUnit.SECONDS) // 整个请求超时
.build();
超时配置建议:
- connectTimeout: 10-15秒(建立TCP连接的时间)
- readTimeout: 30-60秒(等待服务器响应的时间)
- writeTimeout: 30-60秒(向服务器写入数据的时间)
- callTimeout: 60-120秒(整个请求流程的时间)
7.3 避免主线程阻塞
❌ 错误做法:
scss
// 在主线程同步执行网络请求
User user = userService.getUser(100).execute().body();
✅ 正确做法:
less
// 使用异步回调
userService.getUser(100).enqueue(new Callback<ApiResponse<User>>() {
@Override
public void onResponse(Call<ApiResponse<User>> call, Response<ApiResponse<User>> response) {
// 处理响应(已在主线程)
}
@Override
public void onFailure(Call<ApiResponse<User>> call, Throwable t) {
// 处理失败
}
});
// 或使用RxJava
userService.getUser(100)
.subscribeOn(Schedulers.io()) // 在IO线程执行
.observeOn(AndroidSchedulers.mainThread()) // 在主线程处理结果
.subscribe(/* ... */);
7.4 合理使用缓存
java
// 配置缓存策略
public class CacheInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
// 无网络时强制使用缓存
if (!isNetworkAvailable()) {
request = request.newBuilder()
.cacheControl(CacheControl.FORCE_CACHE)
.build();
}
Response response = chain.proceed(request);
if (isNetworkAvailable()) {
// 有网络时设置缓存有效期为1分钟
int maxAge = 60;
response = response.newBuilder()
.removeHeader("Pragma")
.removeHeader("Cache-Control")
.header("Cache-Control", "public, max-age=" + maxAge)
.build();
} else {
// 无网络时缓存保留4周
int maxStale = 60 * 60 * 24 * 28;
response = response.newBuilder()
.removeHeader("Pragma")
.removeHeader("Cache-Control")
.header("Cache-Control", "public, only-if-cached, max-stale=" + maxStale)
.build();
}
return response;
}
private boolean isNetworkAvailable() {
// 检查网络连接状态
ConnectivityManager cm = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = cm.getActiveNetworkInfo();
return networkInfo != null && networkInfo.isConnected();
}
}
8. 总结
8.1 Retrofit核心要点
- 架构清晰 - 分层设计,职责明确
- 使用简单 - 声明式API,注解驱动
- 扩展性强 - 支持自定义Converter、CallAdapter、Interceptor
- 性能优秀 - 基于OkHttp,连接复用,缓存支持
- 生态丰富 - 与RxJava、Coroutine等框架无缝集成