Android-开源框架和源码分析-05-Retrofit-源码解析

169 阅读4分钟

Retrofit 是一个流行的 RESTful 网络请求框架,基于 OkHttp 实现,提供了一种简洁且强大的接口来定义和发起网络请求。以下是 Retrofit 的详细源码解析。


Retrofit 架构

Retrofit 的核心组件包括:

  1. Retrofit

    • 配置类,用于初始化框架。
    • 包含请求的基本信息:BaseUrlConverterCallAdapter 等。
  2. ServiceMethod

    • 将接口方法解析为请求的详细信息(如 URL、参数)。
  3. OkHttpCall

    • 基于 OkHttp 实现的 Call 对象,负责发起 HTTP 请求。
  4. Converter

    • 负责将请求和响应数据进行序列化和反序列化(如 JSON、XML)。
  5. CallAdapter

    • 转换 Call 对象为用户需要的类型(如 Call<T>Observable<T>)。

使用流程

基本使用

java
复制代码
Retrofit retrofit = new Retrofit.Builder()
        .baseUrl("https://api.example.com/")
        .addConverterFactory(GsonConverterFactory.create())
        .build();

ApiService apiService = retrofit.create(ApiService.class);
Call<ResponseBody> call = apiService.getData();
call.enqueue(new Callback<ResponseBody>() {
    @Override
    public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
        // 处理响应
    }

    @Override
    public void onFailure(Call<ResponseBody> call, Throwable t) {
        // 处理失败
    }
});

源码解析

1. Retrofit 的初始化

Retrofit 的初始化主要通过 Builder 模式实现:

java
复制代码
public static final class Builder {
    private Platform platform;
    private okhttp3.Call.Factory callFactory;
    private HttpUrl baseUrl;
    private List<Converter.Factory> converterFactories = new ArrayList<>();
    private List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>();

    public Builder baseUrl(String baseUrl) {
        this.baseUrl = HttpUrl.get(baseUrl);
        return this;
    }

    public Builder addConverterFactory(Converter.Factory factory) {
        converterFactories.add(factory);
        return this;
    }

    public Builder addCallAdapterFactory(CallAdapter.Factory factory) {
        callAdapterFactories.add(factory);
        return this;
    }

    public Retrofit build() {
        return new Retrofit(this);
    }
}
  • baseUrl:设置请求的基础 URL。
  • addConverterFactory:添加序列化和反序列化的转换器。
  • addCallAdapterFactory:添加适配器,用于扩展返回类型。

2. 创建 API 接口

通过 Retrofit.create() 方法生成接口实现:

java
复制代码
public <T> T create(final Class<T> service) {
    Utils.validateServiceInterface(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);
                    OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);
                    return serviceMethod.callAdapter.adapt(okHttpCall);
                }
            });
}
  • 动态代理:通过 Proxy 为接口方法生成实现。

  • ServiceMethod

    • 解析接口注解,构建请求细节(如 URL、Headers)。
  • OkHttpCall

    • 执行 HTTP 请求并返回结果。

3. ServiceMethod 解析

ServiceMethod 是核心类之一,负责解析接口方法的注解。

java
复制代码
static <T> ServiceMethod<T> parseAnnotations(Retrofit retrofit, Method method) {
    RequestFactory requestFactory = RequestFactory.parseAnnotations(retrofit, method);
    CallAdapter<T, ?> callAdapter = createCallAdapter(retrofit, method);
    Converter<ResponseBody, T> responseConverter = createResponseConverter(retrofit, method);
    return new ServiceMethod<>(requestFactory, callAdapter, responseConverter);
}
  • RequestFactory

    • 解析接口注解(如 @GET@POST),构建 URL 和请求体。
  • CallAdapter

    • 转换返回类型(如 Call<T>Observable<T>)。
  • Converter

    • 将响应数据转换为目标类型(如 Java 对象)。

4. 发起请求

请求通过 OkHttpCall 实现,enqueue()execute() 负责异步和同步请求。

同步请求

java
复制代码
@Override
public Response<T> execute() throws IOException {
    okhttp3.Call rawCall = createRawCall();
    okhttp3.Response rawResponse = rawCall.execute();
    return parseResponse(rawResponse);
}
  • createRawCall()

    • 基于 OkHttp 构建原始请求。
  • parseResponse()

    • 将响应转换为用户需要的格式。

异步请求

java
复制代码
@Override
public void enqueue(final Callback<T> callback) {
    okhttp3.Call rawCall = createRawCall();
    rawCall.enqueue(new okhttp3.Callback() {
        @Override
        public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse) throws IOException {
            callback.onResponse(OkHttpCall.this, parseResponse(rawResponse));
        }

        @Override
        public void onFailure(okhttp3.Call call, IOException e) {
            callback.onFailure(OkHttpCall.this, e);
        }
    });
}
  • 使用 OkHttp 的异步执行机制,通过回调处理结果。

5. Converter 转换器

Converter 用于序列化和反序列化请求和响应数据。

请求转换

java
复制代码
public RequestBody convert(T value) throws IOException {
    Buffer buffer = new Buffer();
    JsonWriter writer = new JsonWriter(buffer.outputStream());
    gson.toJson(value, type, writer);
    writer.close();
    return RequestBody.create(buffer.readByteString(), MediaType.get("application/json"));
}

响应转换

java
复制代码
public T convert(ResponseBody value) throws IOException {
    JsonReader jsonReader = gson.newJsonReader(value.charStream());
    return gson.fromJson(jsonReader, type);
}
  • GsonConverter 是默认实现,用于 JSON 格式的序列化。

6. CallAdapter 适配器

CallAdapter 用于扩展返回类型,如支持 RxJava、协程等。

示例:RxJava 适配器

java
复制代码
public class RxJavaCallAdapterFactory extends CallAdapter.Factory {
    @Override
    public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
        return new RxJavaCallAdapter();
    }
}

public class RxJavaCallAdapter implements CallAdapter<Call<T>, Observable<T>> {
    @Override
    public Observable<T> adapt(Call<T> call) {
        return Observable.create(emitter -> {
            call.enqueue(new Callback<T>() {
                @Override
                public void onResponse(Call<T> call, Response<T> response) {
                    emitter.onNext(response.body());
                    emitter.onComplete();
                }

                @Override
                public void onFailure(Call<T> call, Throwable t) {
                    emitter.onError(t);
                }
            });
        });
    }
}

性能优化

  1. 基于 OkHttp

    • 复用了 OkHttp 的连接池和多路复用机制。
  2. 动态代理

    • 避免了手动解析请求逻辑,简化开发。
  3. 自定义扩展

    • 支持自定义 ConverterCallAdapter,适配不同场景。
  4. 轻量级架构

    • 通过注解配置请求,减少冗余代码。

总结

Retrofit 是基于 OkHttp 的网络请求框架,提供了强大的注解配置和扩展能力。它的核心特点包括:

  1. 注解驱动:简化接口定义。
  2. 拦截器:灵活的请求和响应处理。
  3. 多种适配器:支持同步、异步、RxJava、协程等。
  4. 高度可扩展:允许用户定制序列化和返回类型。

通过源码分析,可以深入理解 Retrofit 的工作机制,从而更高效地使用它,满足各种复杂场景下的网络请求需求。