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() {
            @Override
            public void onResponse(Call call, Response response) {
            }

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


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

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


package retrofit2;

public final class Retrofit {

  public  T create(final Class 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 {

  static  ServiceMethod 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 extends ServiceMethod {

  static  HttpServiceMethod 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 callAdapter =
        createCallAdapter(retrofit, method, adapterType, annotations); 

    // 从 retrofit 中获取响应转换器
    Converter 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 extends ServiceMethod {

  @Override
  final @Nullable ReturnT invoke(Object[] args) {
    // 创建能够进行网络请求的 Call
    Call 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 implements Call {
    final Executor callbackExecutor; // 这个是用来切换主线程的
    final Call delegate; // 这个就是 OkHttpCall

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

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

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

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

  }
}

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

你可能感兴趣的:(android,retrofit)