Retrofit 最新源码解析 (附源码下载)

Jennifer ·
更新时间:2024-09-20
· 853 次阅读

目录

1. 前言

2. 简介

3. 火热热的4个网络框架

4. 如何使用

5. 源码分析

6. 后记

1. 前言

        今年是2020年了,也是我正式入驻CSDN博客的第一年,说起来也凑巧,因为今年的黑天鹅事件导致我们不得不在家宅着,当然到2月中下旬很多企业都复工了,本人也一样进入了远程办公状态,其实本人挺懒的,写文章这种事情我其实是不怎么热衷的,主要还是因为在家宅久了觉得会不够充实,于是乎有时间去学习下当下流行的Android开发技术,想通过写博客的方式梳理下自己学到的知识点。好了,我就不废话了,直接进入真题吧,以下便是关于我学习Retrofit网络框架的总结。

2. 简介

        Retrofit2是基于OkHttp作了二次封装的网络请求框架,由Square公司开发的,现已流行好几年了,当然大家都知道Square公司是很有名气的,著名全家桶就有okhttp,retrofit,okio,picasso,leakcanary,javapoet等。某某要是问我,Retrofit2哪里好用,相比okhttp好在哪?那么我就只好这么回答了,它适用于后台Api遵循Restful API设计风格的场景,此外,最突出的地方就是对RxJava的完美支持,据博客资源记载,目前最流行的一套网络请求套装大概就是Retrofit+RxJava+Mvp了。还要再夸下它的功能是十分强大的,不仅支持同步和异步请求,还支持多种数据格式解析;简洁易使用,通过注解配置网络请求参数,并运用许多设计模式简化使用;可拓展性好,解耦性高。

3. 火热热的4个网络框架

这里我就直接贴上这四个框架的github热度让大家参考一番,这个最有权威性。

https://github.com/square/retrofit

https://github.com/square/okhttp

https://github.com/google/volley

https://github.com/wyouflf/xUtils3

因为我学习android的时候只用到了OkHttp,最近才用到Retrofit,而Volley和XUtils等其他框架我还没用到过,以后有时间我再去仔细研究下了,所以我暂时只能传递(cv)网友的理解分析一下。

(1)Okhttp:OkHttp是Square公司开源的针对Java和Android程序,封装的一个高性能http请求库,它的职责跟HttpUrlConnection 是一样的,支持 spdy、http 2.0、websocket ,支持同步、异步,而且 OkHttp 又封装了线程池,封装了数据转换,封装了参数使用、错误处理等。该框架使用门槛不高,需要自己稍微封装一下便可方便使用。

(2)Retrofit:对OkHttp的二次封装,使用了大量的注解来简化代码,并且支持RxJava。该框架几乎没有缺点,唯独就是搭配RxJava使用起来会有一定的难度,学习成本高,期间会遇到不少的坑点需要使用者们多去研究下。

(3)Volley:据说很多小伙伴们都在用这套框架,网传其被封装的很好,并支持简单的图片加载,使用者几乎不用再对他进行二次封装了,唯独不好的地方就是不支持post大数据,不能下载文件,以及不适合上传文件。

(4)XUtils:这是我最近才接触到的一个框架,第一次发现它是在我同事负责的项目里有看到的,好像是国人写的,网传它不仅能支持基本的网络请求,还支持图片加载处理,以及数据储存等,缺点是会导致项目对该框架的依赖过重。

那么现在问题来了,到底该用哪套框架到我们的项目中去?我个人觉得还是得看团队的选择,以及实际的项目需求重点,取其所长,补齐所短,才能发挥起框架的最大价值。

4. 如何使用

因为Retrofit使用了大量的注解来处理网络请求参数信息,熟悉其注解的含义自然会是重中之重了,这里我就cv一下Carson_Ho大神的图片资源(来自https://blog.csdn.net/carson_ho/article/details/73732076),大家要先了解下其中的注解名词,关于注解的具体含义可以参考下丨Fan的文章(来自https://www.jianshu.com/p/8e1b76b8939d),这样后面就会看的懂一些。

5. 源码分析

5.1 UML类图(省略掉成员属性)

这里附上UML类图的作法链接:http://www.uml.org.cn/oobject/20111271.asp  以及 https://www.cnblogs.com/wanghuaijun/p/5421419.html

5.2 源码流程(1)之 创建Retrofit实例

相信各位老铁已经了解了Retrofit使用流程,如果还没了解,也没关系,可以先参考一下第四章节:4.如何使用。

好,根据上面Retrofit实例的创建过程,我先贴下源代码:

  /**
   * Build a new {@link Retrofit}.
   * 

* Calling {@link #baseUrl} is required before calling {@link #build()}. All other methods * are optional. */ public static final class Builder { private final Platform platform; private @Nullable okhttp3.Call.Factory callFactory; private @Nullable HttpUrl baseUrl; private final List converterFactories = new ArrayList(); private final List callAdapterFactories = new ArrayList(); private @Nullable Executor callbackExecutor; private boolean validateEagerly; Builder(Platform platform) { this.platform = platform; } public Builder() { this(Platform.get()); }

说明:

这里Builder类作为Retrofit的内部类,运用到了建造者模式,原理是交由Builder类创建一个一个小组件(这里包括添加baseUrl,请求适配器CallAdapter,数据转换器CallConverter,etc..),最后通过其build方法创建一个最终的目标对象,这是运用建造者模式的广泛作法,其他很多地方几乎都是这么个套用法。

其次,这里我们还看到了Platform类,通过它可以拿到Platform.Android实例,那有什么用呢?先贴下源码:

 /**
     * Create the {@link Retrofit} instance using the configured values.
     * 

* Note: If neither {@link #client} nor {@link #callFactory} is called a default {@link * OkHttpClient} will be created and used. */ public Retrofit build() { if (baseUrl == null) { throw new IllegalStateException("Base URL required."); } okhttp3.Call.Factory callFactory = this.callFactory; if (callFactory == null) { callFactory = new OkHttpClient(); } Executor callbackExecutor = this.callbackExecutor; if (callbackExecutor == null) { callbackExecutor = platform.defaultCallbackExecutor(); } // Make a defensive copy of the adapters and add the default Call adapter. List callAdapterFactories = new ArrayList(this.callAdapterFactories); callAdapterFactories.addAll(platform.defaultCallAdapterFactories(callbackExecutor)); // Make a defensive copy of the converters. List converterFactories = new ArrayList( 1 + this.converterFactories.size() + platform.defaultConverterFactoriesSize()); // Add the built-in converter factory first. This prevents overriding its behavior but also // ensures correct behavior when using converters that consume all types. converterFactories.add(new BuiltInConverters()); converterFactories.addAll(this.converterFactories); converterFactories.addAll(platform.defaultConverterFactories()); return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories), unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly); }

说明:根据注释和源码,我们可以知道:

1.如果之前没有添加okhttp3.Call.Factory的实现类实例的话,就会创建一个OkHttpClient实例,这里大多数情况下让它直接默认创建即可;

2.如果之前没有添加Executor,那么在Android平台会为我们创建一个MainThreadExecutor,这个类其实就是封装了一个主线程的Handler,其用法相信大家也能猜得出来,后面我再提及它;

3.固定添加1~2个请求适配器工厂DefaultCallAdapterFactory和CompletableFutureCallAdapterFactory(要求API24以上);

4.固定添加1~2个数据转换器工厂BuiltInConverters和OptionalConverterFactory(要求API24以上)。

5.完成Retrofit实例创建。

5.3 源码流程(2)之 创建网络请求接口

先上源代码:

@SuppressWarnings("unchecked") // Single-interface proxy creation guarded by parameter safety.
  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 @Nullable 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);
          }
        });
  }

说明:这里运用到了动态代理,即需要事先写好一个网络请求接口,这里假设传一个INetService,通过代码INetService iNetService = retrofit.create(INetService.class)即可创建网络请求接口实例,INetService接口代码示例如下:

public interface INetService { @GET("{subPath}") Call get(@Path("subPath") String subUrl, @QueryMap Map params); //post请求以表单形式传参 @FormUrlEncoded @POST("{subPath}") Call postForm(@Path("subPath") String subUrl, @FieldMap Map params); //post请求以Json形式传参 @POST("{subPath}") Call postJson(@Path("subPath") String subUrl, @Body Object params); @FormUrlEncoded @PUT("{subPath}") Call put(@Path("subPath") String subUrl, @FieldMap Map params); @DELETE("{subPath}") Call delete(@Path("subPath") String subUrl, @QueryMap Map params); @Streaming @GET("{subPath}") Call download(@Header("Range") String range, @Path("subPath") String subUrl, @QueryMap Map params); @Multipart @POST("{subPath}") Call upload(@Path("subPath") String subUrl, @Part List mapFile); }

5.4 源码流程(3)之 执行网络请求

说明:现在我们回过来注意下Retrofit类的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;
  }

说明:这里运用了享元模式,之所以这么做,是为了不去反复的执行解析注解的操作,因为网络接口写好了,就不会在运行期间动态修改,另外就是某接口方法可能会执行多次,若每次都去解析其注解信息的话,就每次都会影响执行效率。

比如,我执行了INetService接口中的get方法,那么会走loadServiceMethod方法,如果是第一次,会先调用ServiceMethod.parseAnnotations(this, method)语句,即解析其方法注解,这里我先贴上源代码:

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 @Nullable T invoke(Object[] args);
}

说明:这里会依赖到RequestFactory类,再上其源码:

  static RequestFactory parseAnnotations(Retrofit retrofit, Method method) {
    return new Builder(retrofit, method).build();
  }
Builder(Retrofit retrofit, Method method) {
      this.retrofit = retrofit;
      this.method = method;
      this.methodAnnotations = method.getAnnotations();
      this.parameterTypes = method.getGenericParameterTypes();
      this.parameterAnnotationsArray = method.getParameterAnnotations();
    }
    RequestFactory build() {
      for (Annotation annotation : methodAnnotations) {
        parseMethodAnnotation(annotation);
      }
      if (httpMethod == null) {
        throw methodError(method, "HTTP method annotation is required (e.g., @GET, @POST, etc.).");
      }
      if (!hasBody) {
        if (isMultipart) {
          throw methodError(method,
              "Multipart can only be specified on HTTP methods with request body (e.g., @POST).");
        }
        if (isFormEncoded) {
          throw methodError(method, "FormUrlEncoded can only be specified on HTTP methods with "
              + "request body (e.g., @POST).");
        }
      }
      int parameterCount = parameterAnnotationsArray.length;
      parameterHandlers = new ParameterHandler[parameterCount];
      for (int p = 0, lastParameter = parameterCount - 1; p < parameterCount; p++) {
        parameterHandlers[p] =
            parseParameter(p, parameterTypes[p], parameterAnnotationsArray[p], p == lastParameter);
      }
      if (relativeUrl == null && !gotUrl) {
        throw methodError(method, "Missing either @%s URL or @Url parameter.", httpMethod);
      }
      if (!isFormEncoded && !isMultipart && !hasBody && gotBody) {
        throw methodError(method, "Non-body HTTP method cannot contain @Body.");
      }
      if (isFormEncoded && !gotField) {
        throw methodError(method, "Form-encoded method must contain at least one @Field.");
      }
      if (isMultipart && !gotPart) {
        throw methodError(method, "Multipart method must contain at least one @Part.");
      }
      return new RequestFactory(this);
    }

说明:第一个for循环是为了遍历解析INetService接口某方法所有注解,往后看,依赖到ParameterHandler类,咋一看类名就知道是用来处理方法参数的,事实上的确如此,ParameterHandler类里头有很多的内部继承者,比如ParameterHandler.Part类,它主要维护了一个数据解析引用(Converter),然后方法apply是为了把调用者传过来的参数值value封装到请求体Requestbody中,并且在这之前会通过Converter做数据解析的操作。

static final class Part extends ParameterHandler { private final Method method; private final int p; private final okhttp3.Headers headers; private final Converter converter; Part(Method method, int p, okhttp3.Headers headers, Converter converter) { this.method = method; this.p = p; this.headers = headers; this.converter = converter; } @Override void apply(RequestBuilder builder, @Nullable T value) { if (value == null) return; // Skip null values. RequestBody body; try { body = converter.convert(value); } catch (IOException e) { throw Utils.parameterError(method, p, "Unable to convert " + value + " to RequestBody", e); } builder.addPart(headers, body); } }

接下来我们来看下HttpServiceMethod类:

static  HttpServiceMethod parseAnnotations(
      Retrofit retrofit, Method method, RequestFactory requestFactory) {
    boolean isKotlinSuspendFunction = requestFactory.isKotlinSuspendFunction;
    boolean continuationWantsResponse = false;
    boolean continuationBodyNullable = false;
    Annotation[] annotations = method.getAnnotations();
    Type adapterType;
    if (isKotlinSuspendFunction) {
      Type[] parameterTypes = method.getGenericParameterTypes();
      Type responseType = Utils.getParameterLowerBound(0,
          (ParameterizedType) parameterTypes[parameterTypes.length - 1]);
      if (getRawType(responseType) == Response.class && responseType instanceof ParameterizedType) {
        // Unwrap the actual body type from Response.
        responseType = Utils.getParameterUpperBound(0, (ParameterizedType) responseType);
        continuationWantsResponse = true;
      } else {
        // TODO figure out if type is nullable or not
        // Metadata metadata = method.getDeclaringClass().getAnnotation(Metadata.class)
        // Find the entry for method
        // Determine if return type is nullable or not
      }
      adapterType = new Utils.ParameterizedTypeImpl(null, Call.class, responseType);
      annotations = SkipCallbackExecutorImpl.ensurePresent(annotations);
    } else {
      adapterType = method.getGenericReturnType();
    }
    CallAdapter callAdapter =
        createCallAdapter(retrofit, method, adapterType, annotations);
    Type responseType = callAdapter.responseType();
    if (responseType == okhttp3.Response.class) {
      throw methodError(method, "'"
          + getRawType(responseType).getName()
          + "' is not a valid response body type. Did you mean ResponseBody?");
    }
    if (responseType == Response.class) {
      throw methodError(method, "Response must include generic type (e.g., Response)");
    }
    // TODO support Unit for Kotlin?
    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;
    if (!isKotlinSuspendFunction) {
      return new CallAdapted(requestFactory, callFactory, responseConverter, callAdapter);
    } else if (continuationWantsResponse) {
      //noinspection unchecked Kotlin compiler guarantees ReturnT to be Object.
      return (HttpServiceMethod) new SuspendForResponse(requestFactory,
          callFactory, responseConverter, (CallAdapter<ResponseT, Call>) callAdapter);
    } else {
      //noinspection unchecked Kotlin compiler guarantees ReturnT to be Object.
      return (HttpServiceMethod) new SuspendForBody(requestFactory,
          callFactory, responseConverter, (CallAdapter<ResponseT, Call>) callAdapter,
          continuationBodyNullable);
    }
  }

说明:ServiceMethod类会调用HttpServiceMethod.parseAnnotations方法,该方法会根据网络请求接口方法的返回类型(比如:Call)来匹配合适的请求适配器CallAdapter,并根据返回类型里的泛型参数类型(比如:BasicResponse)来匹配合适的数据转换器CallConverter,最后返回一个CallAdapted实例。

经过以上一大波操作之后,终于ServiceMethod实例被创建好了,稍微总结一下,期间主要是解析或封装了网路请求接口中的请求头,请求参数信息,以及合适的请求适配器和数据转换器等。下面再回到这里:

return loadServiceMethod(method).invoke(args != null ? args : emptyArgs);

说明:其实loadServiceMethod(Method method)方法做了几乎所有的准备工作,那么接下来的执行任务就交给了HttpServiceMethod类的invoke方法来进行,下面上代码:

 @Override final @Nullable ReturnT invoke(Object[] args) {
    Call call = new OkHttpCall(requestFactory, args, callFactory, responseConverter);
    return adapt(call, args);
  }

说明:创建了OkHttpCall,并且这个OkHttpCall实现了Call接口,下面我们来看下这个类是做什么的。

final class OkHttpCall implements Call {
  private final RequestFactory requestFactory;
  private final Object[] args;
  private final okhttp3.Call.Factory callFactory;
  private final Converter responseConverter;
  private volatile boolean canceled;
  @GuardedBy("this")
  private @Nullable okhttp3.Call rawCall;
  @GuardedBy("this") // Either a RuntimeException, non-fatal Error, or IOException.
  private @Nullable Throwable creationFailure;
  @GuardedBy("this")
  private boolean executed;
  OkHttpCall(RequestFactory requestFactory, Object[] args,
      okhttp3.Call.Factory callFactory, Converter responseConverter) {
    this.requestFactory = requestFactory;
    this.args = args;
    this.callFactory = callFactory;
    this.responseConverter = responseConverter;
  }

说明:看到这里的时候,相信大家已经看到最后的原生rawCall引用了,并且还维护了一个OkHttpClient实例,等等,OkHttpClient实例?对的,就是那个callFactory引用啦,OkHttpClient实例是在构建Retrofit实例的时候被默认创建好的,只不过经过好几轮的传参最后回到了这里才被真正派上用场了。下面再看下:

 private okhttp3.Call createRawCall() throws IOException {
    okhttp3.Call call = callFactory.newCall(requestFactory.create(args));
    if (call == null) {
      throw new NullPointerException("Call.Factory returned null.");
    }
    return call;
  }
@Override public void enqueue(final Callback callback) {
    checkNotNull(callback, "callback == null");
    okhttp3.Call call;
    Throwable failure;
    synchronized (this) {
      if (executed) throw new IllegalStateException("Already executed.");
      executed = true;
      call = rawCall;
      failure = creationFailure;
      if (call == null && failure == null) {
        try {
          call = rawCall = createRawCall();
        } catch (Throwable t) {
          throwIfFatal(t);
          failure = creationFailure = t;
        }
      }
    }
    if (failure != null) {
      callback.onFailure(this, failure);
      return;
    }
    if (canceled) {
      call.cancel();
    }
    call.enqueue(new okhttp3.Callback() {
      @Override public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse) {
        Response response;
        try {
          response = parseResponse(rawResponse);
        } catch (Throwable e) {
          throwIfFatal(e);
          callFailure(e);
          return;
        }
        try {
          callback.onResponse(OkHttpCall.this, response);
        } catch (Throwable t) {
          throwIfFatal(t);
          t.printStackTrace(); // TODO this is not great
        }
      }
      @Override public void onFailure(okhttp3.Call call, IOException e) {
        callFailure(e);
      }
      private void callFailure(Throwable e) {
        try {
          callback.onFailure(OkHttpCall.this, e);
        } catch (Throwable t) {
          throwIfFatal(t);
          t.printStackTrace(); // TODO this is not great
        }
      }
    });
  }

说明:到这里相信大家已经知道,这里便是我们封装OkHttp网络请求的熟悉代码了。先得到原生rawCall,这里用到了RequestFactory类,根据newCall方法我们就知道RequestFactory就是用来创建Request请求对象的。我先贴上源代码:

final class RequestFactory {
  static RequestFactory parseAnnotations(Retrofit retrofit, Method method) {
    return new Builder(retrofit, method).build();
  }
  private final Method method;
  private final HttpUrl baseUrl;
  final String httpMethod;
  private final @Nullable String relativeUrl;
  private final @Nullable Headers headers;
  private final @Nullable MediaType contentType;
  private final boolean hasBody;
  private final boolean isFormEncoded;
  private final boolean isMultipart;
  private final ParameterHandler[] parameterHandlers;
  final boolean isKotlinSuspendFunction;
  RequestFactory(Builder builder) {
    method = builder.method;
    baseUrl = builder.retrofit.baseUrl;
    httpMethod = builder.httpMethod;
    relativeUrl = builder.relativeUrl;
    headers = builder.headers;
    contentType = builder.contentType;
    hasBody = builder.hasBody;
    isFormEncoded = builder.isFormEncoded;
    isMultipart = builder.isMultipart;
    parameterHandlers = builder.parameterHandlers;
    isKotlinSuspendFunction = builder.isKotlinSuspendFunction;
  }
  okhttp3.Request create(Object[] args) throws IOException {
    @SuppressWarnings("unchecked") // It is an error to invoke a method with the wrong arg types.
    ParameterHandler[] handlers = (ParameterHandler[]) parameterHandlers;
    int argumentCount = args.length;
    if (argumentCount != handlers.length) {
      throw new IllegalArgumentException("Argument count (" + argumentCount
          + ") doesn't match expected count (" + handlers.length + ")");
    }
    RequestBuilder requestBuilder = new RequestBuilder(httpMethod, baseUrl, relativeUrl,
        headers, contentType, hasBody, isFormEncoded, isMultipart);
    if (isKotlinSuspendFunction) {
      // The Continuation is the last parameter and the handlers array contains null at that index.
      argumentCount--;
    }
    List argumentList = new ArrayList(argumentCount);
    for (int p = 0; p < argumentCount; p++) {
      argumentList.add(args[p]);
      handlers[p].apply(requestBuilder, args[p]);
    }
    return requestBuilder.get()
        .tag(Invocation.class, new Invocation(method, argumentList))
        .build();
  }

说明:这里别看RequestFactory维护了大量的引用,其实唯一做了一件最有意义的事情就是创建RequestBuilder类对象,下面我们来看下RequestBuilder类:

Request.Builder get() {
    HttpUrl url;
    HttpUrl.Builder urlBuilder = this.urlBuilder;
    if (urlBuilder != null) {
      url = urlBuilder.build();
    } else {
      // No query parameters triggered builder creation, just combine the relative URL and base URL.
      //noinspection ConstantConditions Non-null if urlBuilder is null.
      url = baseUrl.resolve(relativeUrl);
      if (url == null) {
        throw new IllegalArgumentException(
            "Malformed URL. Base: " + baseUrl + ", Relative: " + relativeUrl);
      }
    }
    RequestBody body = this.body;
    if (body == null) {
      // Try to pull from one of the builders.
      if (formBuilder != null) {
        body = formBuilder.build();
      } else if (multipartBuilder != null) {
        body = multipartBuilder.build();
      } else if (hasBody) {
        // Body is absent, make an empty body.
        body = RequestBody.create(null, new byte[0]);
      }
    }
    MediaType contentType = this.contentType;
    if (contentType != null) {
      if (body != null) {
        body = new ContentTypeOverridingRequestBody(body, contentType);
      } else {
        headersBuilder.add("Content-Type", contentType.toString());
      }
    }
    return requestBuilder
        .url(url)
        .headers(headersBuilder.build())
        .method(method, body);
  }

说明:是否对这里的代码灰常的熟悉,下面我贴下OkHttp的常用代码:

OkHttpClient client = new OkHttpClient();//创建OkHttpClient对象。
MediaType JSON = MediaType.parse("application/json; charset=utf-8");//数据类型为json格式,
String jsonStr = "{\"username\":\"lisi\",\"nickname\":\"李四\"}";//json数据.
RequestBody body = RequestBody.create(JSON, josnStr);
Request request = new Request.Builder()
        .url("http://www.baidu.com")
        .post(body)
        .build();
client.newCall(request).enqueue(new Callback() { ....});

说明:很明显RequestBuilder根据不同的请求方式来实例化一个合适的请求体RequestBody,这个请求体可能是FormBody,RequestBody,MultipartBody等,最后再以Request.Builder对象返回。

  @Override final @Nullable ReturnT invoke(Object[] args) {
    Call call = new OkHttpCall(requestFactory, args, callFactory, responseConverter);
    return adapt(call, args);
  }
  protected abstract @Nullable ReturnT adapt(Call call, Object[] args);
  static final class CallAdapted extends HttpServiceMethod {
    private final CallAdapter callAdapter;
    CallAdapted(RequestFactory requestFactory, okhttp3.Call.Factory callFactory,
        Converter responseConverter,
        CallAdapter callAdapter) {
      super(requestFactory, callFactory, responseConverter);
      this.callAdapter = callAdapter;
    }
    @Override protected ReturnT adapt(Call call, Object[] args) {
      return callAdapter.adapt(call);
    }
  }

说明:通过invoke方法拿到我们的Call接口,通过CallAdapted类代理了一个CallAdapter接口引用,这里默认就是我们之前匹配好的合适的请求适配器,如果要问它在哪里?它在DefaultCallAdapterFactory工厂类里匿名内部类实现了。贴下源码:

final class DefaultCallAdapterFactory extends CallAdapter.Factory {
  private final @Nullable Executor callbackExecutor;
  DefaultCallAdapterFactory(@Nullable Executor callbackExecutor) {
    this.callbackExecutor = callbackExecutor;
  }
  @Override public @Nullable CallAdapter get(
      Type returnType, Annotation[] annotations, Retrofit retrofit) {
    if (getRawType(returnType) != Call.class) {
      return null;
    }
    if (!(returnType instanceof ParameterizedType)) {
      throw new IllegalArgumentException(
          "Call return type must be parameterized as Call or Call");
    }
    final Type responseType = Utils.getParameterUpperBound(0, (ParameterizedType) returnType);
    final Executor executor = Utils.isAnnotationPresent(annotations, SkipCallbackExecutor.class)
        ? null
        : callbackExecutor;
    return new CallAdapter<Object, Call>() {
      @Override public Type responseType() {
        return responseType;
      }
      @Override public Call adapt(Call call) {
        return executor == null
            ? call
            : new ExecutorCallbackCall(executor, call);
      }
    };
  }
 static final class ExecutorCallbackCall implements Call {
    final Executor callbackExecutor;
    final Call delegate;
    ExecutorCallbackCall(Executor callbackExecutor, Call delegate) {
      this.callbackExecutor = callbackExecutor;
      this.delegate = delegate;
    }
    @Override public void enqueue(final Callback callback) {
      checkNotNull(callback, "callback == null");
      delegate.enqueue(new Callback() {
        @Override public void onResponse(Call call, final Response response) {
          callbackExecutor.execute(new Runnable() {
            @Override public void run() {
              if (delegate.isCanceled()) {
                // Emulate OkHttp's behavior of throwing/delivering an IOException on cancellation.
                callback.onFailure(ExecutorCallbackCall.this, new IOException("Canceled"));
              } else {
                callback.onResponse(ExecutorCallbackCall.this, response);
              }
            }
          });
        }
        @Override public void onFailure(Call call, final Throwable t) {
          callbackExecutor.execute(new Runnable() {
            @Override public void run() {
              callback.onFailure(ExecutorCallbackCall.this, t);
            }
          });
        }
      });
    }

说明:这里ExecutorCallbackCall其实是个代理类,它代理了Call对象,以及维护了一个Executor引用,这个Executor其实就是那个MainThreadExecutor。调用者最后拿到的对象就是ExecutorCallbackCall,通过它走enqueue方法,再通过MainThreadExecutor实现了在主线程回调接口方法。over~

6. 后记

       写这篇文章花了我几天时间吧,文章概括的内容是肯定不完善的,我后续还会继续更新的,亲爱的老铁们若发现文章有误的地方可以在下方评论留言,或者私聊我一下也行的,我好及时更正,以免误导新手,希望能和大家在Android领域里共同进步。

参考链接:

https://blog.csdn.net/carson_ho/article/details/73732076

https://www.jianshu.com/p/8e1b76b8939d

https://blog.csdn.net/lmj623565791/article/details/51304204

https://blog.csdn.net/fightingXia/article/details/70947701

源码下载:

https://github.com/ddgFh/RetrofitDemo/tree/master


作者:IronMan_23



源码下载 retrofit 源码

需要 登录 后方可回复, 如果你还没有账号请 注册新账号