源码解析Retrofit

1.Retrofit创建过程

首先 创建一个Retrofit 代码如下:

    fun ProvidesRetrofit(okHttpClient: OkHttpClient): Retrofit {
        var builder = Retrofit.Builder()
                //设置baseUrl
                .baseUrl(ApiService.BASE_URL)
                 //添加一个返回的数据支持转换为Gson对象,其最终会返回配置好的Retrofit类
                .addConverterFactory(GsonConverterFactory.create())
                 //rxjava2的Call进行转化的对象  
                 // .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) //当你使用RxJava的时候要添加这个
                 //设置OkHttpClient
                .client(okHttpClient)
        return builder.build()
    }

retrofit是通过建造者模式构建出来的。接下来看Builder方法:

public Builder() {
      this(Platform.get());
    }

查看Platform.get()

 private static Platform findPlatform() {
    try {
      Class.forName("android.os.Build");
      if (Build.VERSION.SDK_INT != 0) {
        return new Android();
      }
    } catch (ClassNotFoundException ignored) {
    }
    try {
      Class.forName("java.util.Optional");
      return new Java8();
    } catch (ClassNotFoundException ignored) {
    }
    return new Platform();
  }

最终调用了findPlatform()方法,根据不同的运行平台提供不用的线程池。

接下来看build方法:

public Retrofit build() {
     //baseUrl 必须不为空,否则就包异常了
      if (baseUrl == null) {
        throw new IllegalStateException("Base URL required.");
      }
     //this.callFactory是我们构建Retrofit时调用了client方法传进来的
      okhttp3.Call.Factory callFactory = this.callFactory;
      if (callFactory == null) {
          //如果没有设置callFactory则直接创建OkHttpClient
        callFactory = new OkHttpClient();
      }

      //callbackExecutor 用来回调传递到UI线程
      Executor callbackExecutor = this.callbackExecutor;
      if (callbackExecutor == null) {
        callbackExecutor = platform.defaultCallbackExecutor();
      }

      //adapterFactories 主要用于存储对Call进行转化的对象
      List<CallAdapter.Factory> adapterFactories = new ArrayList<>(this.adapterFactories);
      adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));

      // converterFactories 主要用于存储转化数据对象
      List<Converter.Factory> converterFactories = new ArrayList<>(this.converterFactories);

      return new Retrofit(callFactory, baseUrl, converterFactories, adapterFactories,
          callbackExecutor, validateEagerly);
    }
  }

client方法 则会调用callFactory方法给this.callFactory 赋值

 public Builder client(OkHttpClient client) {
      return callFactory(checkNotNull(client, "client == null"));
    }


 public Builder callFactory(okhttp3.Call.Factory factory) {
     //赋值
      this.callFactory = checkNotNull(factory, "factory == null");
      return this;
    }

2.Call的创建过程

下面创建Retrofit实列并调用如下代码来生成接口的动态代理对象:

var apiserver=retrofit.create(ApiService::class.java)

看看retrofit的create方法:

public <T> T create(final Class<T> service) {
    Utils.validateServiceInterface(service);
    if (validateEagerly) {
      eagerlyValidateMethods(service);
    }
      //返回一个Proxy.newProxyInstance动态代理对象,当我们调用ApiServier的 xxx方法时,最终会调用InvocationHandler的invoke方法
    return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
        new InvocationHandler() {
          private final Platform platform = Platform.get();

          @Override public Object invoke(Object proxy, Method method, 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);
            }
              //method 是我们定义在ApiServier里面的 xxx方法
            ServiceMethod<Object, Object> serviceMethod =
                (ServiceMethod<Object, Object>) loadServiceMethod(method);
             //这里发起请求
            OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
            return serviceMethod.callAdapter.adapt(okHttpCall);
          }
        });
  }

loadServiceMethod方法:

private final Map<Method, ServiceMethod<?, ?>> serviceMethodCache = new ConcurrentHashMap<>();
  ServiceMethod<?, ?> loadServiceMethod(Method method) {
      //读取缓存
    ServiceMethod<?, ?> result = serviceMethodCache.get(method);
      //如果有缓存 直接返回
    if (result != null) return result;
    synchronized (serviceMethodCache) {
      result = serviceMethodCache.get(method);
      if (result == null) {
          //没有创建一个,并加入serviceMethodCache缓存
        result = new ServiceMethod.Builder<>(this, method).build();
        serviceMethodCache.put(method, result);
      }
    }
    return result;
  }

再看ServiceMethod怎样构建的:

    public ServiceMethod build() {
     // 会最终得到们在构建Retrofit调用build方法时 adapterFactories添加对象的get方法 下面给出了说明
      callAdapter = createCallAdapter();
     //得到的是返回数据的真是类型
      responseType = callAdapter.responseType();
      if (responseType == Response.class || responseType == okhttp3.Response.class) {
        throw methodError("'"
            + Utils.getRawType(responseType).getName()
            + "' is not a valid response body type. Did you mean ResponseBody?");
      }
   //来遍历converterFactory列表中存储的Converter.Factory,并返回一个合适的Converter用来转换对象
   //在构建Retrorfit调用了addConverterFactory(GsonConverterFactory.create()),将GsonConverterFactory(Converter.Factory的子类)添加到converterFactories列表中,表示返回的数据支持转换为JSON对象
      responseConverter = createResponseConverter();

      for (Annotation annotation : methodAnnotations) {
     //方法来对请求方式(比如GET、POST)和请求地址进行过解析 会调用->  parseHttpMethodAndPath()
        parseMethodAnnotation(annotation);
      }
     
      ...
      //对方法中的参数注解进行解析 比如(@Query、@Part)
        Annotation[] parameterAnnotations = parameterAnnotationsArray[p];
        if (parameterAnnotations == null) {
          throw parameterError(p, "No Retrofit annotation found.");
        }

        parameterHandlers[p] = parseParameter(p, parameterType, parameterAnnotations);
      }
      ...
 
      return new ServiceMethod<>(this);
    }

ServiceMethod :包含所有网络请求信息的对象

Retrofit的build部分代码:

List<CallAdapter.Factory> adapterFactories = new ArrayList<>(this.adapterFactories);
 //adapterFactories 默认会添加defaultCallAdapterFactory。
adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));

defaultCallAdapterFactory指的是ExecutorCallAdapterFactory

  CallAdapter.Factory defaultCallAdapterFactory(Executor callbackExecutor) {
    if (callbackExecutor != null) {
      return new ExecutorCallAdapterFactory(callbackExecutor);
    }
    return DefaultCallAdapterFactory.INSTANCE;
  }

ExecutorCallAdapterFactory的get方法:

 @Override
  public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
    if (getRawType(returnType) != Call.class) {
      return null;
    }
    final Type responseType = Utils.getCallResponseType(returnType);
  //返回CallAdapter对象
    return new CallAdapter<Object, Call<?>>() {
      @Override public Type responseType() {
    //返回数据的真是类型
        return responseType;
      }

      @Override public Call<Object> adapt(Call<Object> call) {
  //创建 ExecutorCallbackCall 作用 将call的回调转发至UI线程
        return new ExecutorCallbackCall<>(callbackExecutor, call);
      }
    };
  }

responseType 比如 传入Call<xxxBean>,responseType方法就会返回xxxBean。

再看ExecutorCallbackCall方法:

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

    @Override public void enqueue(final Callback<T> callback) {
      if (callback == null) throw new NullPointerException("callback == null");
//方法最终调用delegate的enqueue方法。delegate是传入的OkHttpCall
      delegate.enqueue(new Callback<T>() {
        @Override public void onResponse(Call<T> call, final Response<T> 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<T> call, final Throwable t) {
          callbackExecutor.execute(new Runnable() {
            @Override public void run() {
              callback.onFailure(ExecutorCallbackCall.this, t);
            }
          });
        }
      });
    }

主要是实现了Call接口 和对Call接口的封装,他主要添加了通过Retrofit的callbackExecutor将请求回调到UI线程,Call会调用他的enqueue方法,其实调用的是ExecutorCallbackCall的enqueue

3.Call的enqueue方法

来看OkHttpCall的enqueue

  @Override public void enqueue(final Callback<T> callback) {
    if (callback == null) throw new NullPointerException("callback == null");

    okhttp3.Call call;
    Throwable failure;

    ... 
  //调用okhttp3的call的enqueue
    call.enqueue(new okhttp3.Callback() {
      @Override public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse)
          throws IOException {
        Response<T> response;
        try {
 
          response = parseResponse(rawResponse);
        } catch (Throwable e) {
          callFailure(e);
          return;
        }
        callSuccess(response);
      }

      @Override public void onFailure(okhttp3.Call call, IOException e) {
        try {
          callback.onFailure(OkHttpCall.this, e);
        } catch (Throwable t) {
          t.printStackTrace();
        }
      }

      private void callFailure(Throwable e) {
        try {
          callback.onFailure(OkHttpCall.this, e);
        } catch (Throwable t) {
          t.printStackTrace();
        }
      }

      private void callSuccess(Response<T> response) {
        try {
          callback.onResponse(OkHttpCall.this, response);
        } catch (Throwable t) {
          t.printStackTrace();
        }
      }
    });
  }

parseResponse方法 返回一个response

Response<T> parseResponse(okhttp3.Response rawResponse) throws IOException {
    ResponseBody rawBody = rawResponse.body();

    // Remove the body's source (the only stateful object) so we can pass the response along.
    rawResponse = rawResponse.newBuilder()
        .body(new NoContentResponseBody(rawBody.contentType(), rawBody.contentLength()))
        .build();

    int code = rawResponse.code();
    if (code < 200 || code >= 300) {
      try {
        // Buffer the entire body to avoid future I/O.
        ResponseBody bufferedBody = Utils.buffer(rawBody);
        return Response.error(bufferedBody, rawResponse);
      } finally {
        rawBody.close();
      }
    }

    if (code == 204 || code == 205) {
      rawBody.close();
      return Response.success(null, rawResponse);
    }

    ExceptionCatchingRequestBody catchingBody = new ExceptionCatchingRequestBody(rawBody);
    try {
//解析数据返回body,在此前例子 我们传入的是GsonConverterFactory
      T body = serviceMethod.toResponse(catchingBody);
      return Response.success(body, rawResponse);
    } catch (RuntimeException e) {
      // If the underlying source threw an exception, propagate that rather than indicating it was
      // a runtime exception.
      catchingBody.throwIfCaught();
      throw e;
    }
  }

根据返回的的不同状态吗code来做不同操作,

总结:Call的enqueue方法主要是用于OkHttp来请求网络,将返回的Response进行数据转换并回调给UI线程。

写的不是很好 欢迎各位大佬交流指点

    原文作者:Android_皮皮虾
    原文地址: https://www.jianshu.com/p/6542e315bd61
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞