retrofit源码流程

前言

retrofit 是一个类型安全的http 客户端库。是对okhttp的封装。

使用:

 * Retrofit retrofit = new Retrofit.Builder()
 *     .baseUrl("https://api.example.com/")
 *     .addConverterFactory(GsonConverterFactory.create())
 *     .build();
 *
 * MyApi api = retrofit.create(MyApi.class);
 * Response user = api.getUser().execute();

1.retrofit创建:
retrofit主要包括:

  • callFactory --OkHttpClient

  • baseUrl --传入的域名

  • converterFactories
    转换器的工厂列表, Converter.Factory 接口实现, 抽象工厂模式。
    包括responseBodyConverter,
    requestBodyConverter, RequestFactory解析@body标签时 使用。
    stringConverter RequestFactory解析@query标签时 使用。
    默认,加入BuiltInConverters。

  • callAdapterFactories

默认时 接口返回Call类型。
CallAdpater用于将Call适配到其他类型。
注 : ResponseBody由Converter负责转换。
默认时 java平台加入DefaultCallAdapterFactory
android 加入ExecutorCallAdapterFactory:不改变返回值类型,只做线程切换。

2.创建接口代理实现:

public  T create(final Class service) {
    Utils.validateServiceInterface(service);
    if (validateEagerly) {
      eagerlyValidateMethods(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 Object invoke(Object proxy, Method method, @Nullable Object[] args)
              throws Throwable {
            // If the method is a method from Object then defer to normal invocation.
            if (method.getDeclaringClass() == Object.class) {
              return method.invoke(this, args);
            }
            if (platform.isDefaultMethod(method)) {
              return platform.invokeDefaultMethod(method, service, proxy, args);
            }
            return loadServiceMethod(method).invoke(args != null ? args : emptyArgs);
          }
        });
  }

生成的代理 调用时,相当于调用
loadServiceMethod(method).invoke()
每个接口方法对应于一个ServiceMethod对象。

abstract class ServiceMethod {
  static  ServiceMethod parseAnnotations(Retrofit retrofit, Method method) {
    RequestFactory requestFactory = RequestFactory.parseAnnotations(retrofit, method);

    Type returnType = method.getGenericReturnType();
    if (Utils.hasUnresolvableType(returnType)) {
      throw methodError(method,
          "Method return type must not include a type variable or wildcard: %s", returnType);
    }
    if (returnType == void.class) {
      throw methodError(method, "Service methods cannot return void.");
    }

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

  abstract T invoke(Object[] args);
}

static  HttpServiceMethod parseAnnotations(
      Retrofit retrofit, Method method, RequestFactory requestFactory) {
    CallAdapter callAdapter = createCallAdapter(retrofit, method);
    Type responseType = callAdapter.responseType();
    if (responseType == Response.class || responseType == okhttp3.Response.class) {
      throw methodError(method, "'"
          + Utils.getRawType(responseType).getName()
          + "' is not a valid response body type. Did you mean ResponseBody?");
    }
    if (requestFactory.httpMethod.equals("HEAD") && !Void.class.equals(responseType)) {
      throw methodError(method, "HEAD method must use Void as response type.");
    }

    Converter responseConverter =
        createResponseConverter(retrofit, method, responseType);

    okhttp3.Call.Factory callFactory = retrofit.callFactory;
    return new HttpServiceMethod<>(requestFactory, callFactory, callAdapter, responseConverter);
  }

ServiceMethod对象 根据注解创建。
3.调用接口:
HttpServiceMethod.java

@Override ReturnT invoke(Object[] args) {
    return callAdapter.adapt(
        new OkHttpCall<>(requestFactory, args, callFactory, responseConverter));
  }

生成OkHttpCall对象,并通过callAdapter适配到特定类型。


参考:
https://square.github.io/retrofit/

你可能感兴趣的:(retrofit源码流程)