Android Retrofit 源码解析

在 Android 开发中,Retrofit 是一个非常流行的网络请求库。它是由 Square 开发的,用于简化 Android 应用程序与网络服务器之间的通信

Retrofit 主要用于处理 RESTful API 的网络请求。它通过将 HTTP 请求与 Java 接口方法进行映射,使得网络请求的编写变得简单和直观。使用 Retrofit,开发者可以定义一个描述网络请求的接口,然后通过注解将请求的URL、请求方法、请求参数等信息与接口方法绑定起来。Retrofit 会处理底层的网络请求和数据解析,开发者只需要关注业务逻辑的实现。


Retrofit 的使用:

        // retrofit 初始化
        retrofit = new Retrofit.Builder()
                .baseUrl("https://www.wanandroid.com/")
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .addConverterFactory(GsonConverterFactory.create(new Gson()))
                .build();

        // 创建接口服务
        INetService iNetService = retrofit.create(INetService.class);

        // 进行网络请求
        iNetService.someThingCall().enqueue(new Callback<Bean>() {
            @Override
            public void onResponse(Call<Bean> call, Response<Bean> response) {
            }

            @Override
            public void onFailure(Call<Bean> call, Throwable t) { }
        });


// 服务接口
interface INetService {
    Call<Bean> someThingCall();
}

这就是 Retrofit 的一个常规使用,先初始化,接着创建接口服务,接着就可以进行网络请求了,可以说比 Okhttp 简洁非常多。关键就是 Retrofit.create() 这个方法,里面做了非常多的事


package retrofit2;

public final class Retrofit {

  public <T> T create(final Class<T> service) {
    validateServiceInterface(service); // 验证接口类
    return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] {service},
            new InvocationHandler() {
              @Override
              public Object invoke(Object proxy, Method method, Object[] args)
                  throws Throwable {
                // ....
                return platform.isDefaultMethod(method)
                    ? platform.invokeDefaultMethod(method, service, proxy, args)
                    : loadServiceMethod(method).invoke(args);
              }
            });
  }
}

可以看到,create 方法中使用了动态代理,返回的是 loadServiceMethod(method).invoke(args);

加载服务方法然后去执行,先看 loadServiceMethod:


  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;
  }

会先从缓存中取,若没有缓存则调用 ServiceMethod.parseAnnotations():


package retrofit2;

abstract class ServiceMethod<T> {

  static <T> ServiceMethod<T> parseAnnotations(Retrofit retrofit, Method method) {
    RequestFactory requestFactory = RequestFactory.parseAnnotations(retrofit, method);

    Type returnType = method.getGenericReturnType();
    // ... 对返回类型做判断

    return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
  }
}

这个静态方法主要是对返回类型做判断,收集请求相关的信息整理到 requestFactory 这个对象当中,再调用 HttpServiceMethod.parseAnnotations() :


package retrofit2;

abstract class HttpServiceMethod<ResponseT, ReturnT> extends ServiceMethod<ReturnT> {

  static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations(
      Retrofit retrofit, Method method, RequestFactory requestFactory) {
    boolean isKotlinSuspendFunction = requestFactory.isKotlinSuspendFunction;

    Annotation[] annotations = method.getAnnotations();
    Type adapterType;
    if (isKotlinSuspendFunction) {
      // Kotlin 协程相关
    } else {
      adapterType = method.getGenericReturnType();
    }

    // 从 retrofit 中获取请求适配器
    CallAdapter<ResponseT, ReturnT> callAdapter =
        createCallAdapter(retrofit, method, adapterType, annotations); 

    // 从 retrofit 中获取响应转换器
    Converter<ResponseBody, ResponseT> responseConverter =
        createResponseConverter(retrofit, method, responseType); 

    okhttp3.Call.Factory callFactory = retrofit.callFactory;
    if (!isKotlinSuspendFunction) {
      return new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter);
    } else {
      // Kotlin 协程相关
    }
  }

}

最终,Retrofit.create() 方法中的 loadServiceMethod() 返回的是一个具有请求信息、okhttp 的请求工厂、响应转换器和请求适配器的 CallAdapted


接着,调用 loadServiceMethod().invoke():

package retrofit2;

abstract class HttpServiceMethod<ResponseT, ReturnT> extends ServiceMethod<ReturnT> {

  @Override
  final @Nullable ReturnT invoke(Object[] args) {
    // 创建能够进行网络请求的 Call
    Call<ResponseT> call = new OkHttpCall<>(requestFactory, args, callFactory, responseConverter);
    return adapt(call, args);
  }

}

此时,会将之前的所有请求相关的参数,条件都封装到具有网络请求功能的 OkHttpCall,然后和请求参数一起适配到之前的适配器当中。


最终,返回的 Call 是 DefaultCallAdapterFactory.ExecutorCallbackCall:

package retrofit2;

final class DefaultCallAdapterFactory extends CallAdapter.Factory {

  static final class ExecutorCallbackCall<T> implements Call<T> {
    final Executor callbackExecutor; // 这个是用来切换主线程的
    final Call<T> delegate; // 这个就是 OkHttpCall

    ExecutorCallbackCall(Executor callbackExecutor, Call<T> delegate) {
      this.callbackExecutor = callbackExecutor;
      this.delegate = delegate;
    }

    @Override
    public void enqueue(final Callback<T> callback) {  // 异步请求
      delegate.enqueue(new Callback<T>() {
            @Override
            public void onResponse(Call<T> call, final Response<T> response) {
              callbackExecutor.execute(() -> {
                    if (delegate.isCanceled()) {
                      callback.onFailure(ExecutorCallbackCall.this, new IOException("Canceled"));
                    } else {
                      callback.onResponse(ExecutorCallbackCall.this, response);
                    }
                  });
            }

            @Override
            public void onFailure(Call<T> call, final Throwable t) {
              callbackExecutor.execute(() -> callback.onFailure(ExecutorCallbackCall.this, t));
            }
          });
    }

    @Override
    public Response<T> execute() throws IOException {  // 同步请求
      return delegate.execute();
    }

  }
}

总的来说,Retrofit是一个功能强大、易于使用的网络请求库,它简化了安卓应用程序与服务器之间的通信,提供了方便的接口定义和数据解析功能,是安卓开发中常用的网络请求工具之一。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值