retrofit2源码分析

先从Retrofit的使用开始介绍。一个简单的使用例子如下:

    Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://172.18.157.142:8080")
                //.addConverterFactory(GsonConverterFactory.create())
                .build();

        TestApi testApi = retrofit.create(TestApi.class);

        Map<String,String> p = new HashMap<>();
        p.put("key","123");
        Call<ResponseBody> userCall = testApi.getTestResult("/user/nothing",p);

        userCall.enqueue(new Callback<ResponseBody>() {
            @Override
            public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {

            }

            @Override
            public void onFailure(Call<ResponseBody> call, Throwable t) {
                System.out.println("================onFailure");
            }
        });

okhttp使用例子:

OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
        .url("http://publicobject.com/helloworld.txt")
        .build();
client.newCall(request).enqueue(new Callback() {
      @Override
      public void onFailure(Call call, IOException e) {
            e.printStackTrace();
      }
      @Override
      public void onResponse(Call call, Response response) throws IOException {
      }
});

下面看他们是如何联系的(retrofit是基于okhttp3封装的)

TestApi的源码入下:

interface TestApi {

    @GET("{path}")
    Call<ResponseBody> getTestResult(@Path("path") String path, @QueryMap(encoded = true)Map<String,String> options);

}

Retrofit的使用步骤还是比较麻烦的,主要有如下步骤:
1 创建一个Retrofit实例
2 根据具体的网络请求,创建一个接口,此接口的方法主要用于传入url和参数。
3 根据第二步创建的接口,获取一个Call。
4 调用Call的异步方法enqueue获取返回数据。

下面就从源码的角度详细分析Retrofit的原理。
先从第一步的build()方法开始,build()方法源码如下:

public Retrofit build() { if (baseUrl == null) { throw new IllegalStateException("Base URL required."); } okhttp3.Call.Factory callFactory = this.callFactory; if (callFactory == null) { callFactory = new OkHttpClient();//默认的Factory,可配置 } Executor callbackExecutor = this.callbackExecutor;//返回回调的线程 if (callbackExecutor == null) { callbackExecutor = platform.defaultCallbackExecutor();//默认是主线程 } // Make a defensive copy of the adapters and add the default Call adapter. List<CallAdapter.Factory> adapterFactories = new ArrayList<>(this.adapterFactories); adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor)); // Make a defensive copy of the converters. List<Converter.Factory> converterFactories = new ArrayList<>(this.converterFactories); return new Retrofit(callFactory, baseUrl, converterFactories, adapterFactories, callbackExecutor, validateEagerly); }

接下来看Retrofit的create()方法,源码如下:

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

          @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) {//Object的相关方法不能被代理
              return method.invoke(this, args);
            }
            if (platform.isDefaultMethod(method)) {//可以不用管,java里面用到,android平台默认为false
              return platform.invokeDefaultMethod(method, service, proxy, args);
            }
            ServiceMethod<Object, Object> serviceMethod =
                (ServiceMethod<Object, Object>) loadServiceMethod(method);//获取ServiceMethod
            OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);//创建OkHttpCall
            return serviceMethod.callAdapter.adapt(okHttpCall);//动态代理的拦截执行
          }
        });
  }

create()方法返回了一个动态代理,从create()方法也可以看出,其参数service必须是一个接口,这个是动态代理的机制决定,有关动态代理相关知识,请自行百度。
Method的getDeclaringClass()方法返回Method定义所在的类。
动态代理最后调用了ServiceMethod的CallAdapter的adapt()方法。
ServiceMethod的CallAdapter是怎么初始化的呢?还需要从loadServiceMethod()这个方法说起。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 = new ServiceMethod.Builder<>(this, method).build();//如果result中没有满足需求的ServiceMethod,就创建一个
        serviceMethodCache.put(method, result);
      }
    }
    return result;
  }

ServiceMethod.Builder的build()方法源码如下:

    public ServiceMethod build() {
      callAdapter = createCallAdapter();//创建CallAdapter
      …...
      return new ServiceMethod<>(this);
    }

createCallAdapter()方法源码如下:

    private CallAdapter<T, R> createCallAdapter() {
      Type returnType = method.getGenericReturnType();
      if (Utils.hasUnresolvableType(returnType)) {
        throw methodError(
            "Method return type must not include a type variable or wildcard: %s", returnType);
      }
      if (returnType == void.class) {
        throw methodError("Service methods cannot return void.");
      }
      Annotation[] annotations = method.getAnnotations();
      try {
        //noinspection unchecked
        return (CallAdapter<T, R>) retrofit.callAdapter(returnType, annotations);//从Retrofit中获取。
      } catch (RuntimeException e) { // Wide exception range because factories are user code.
        throw methodError(e, "Unable to create call adapter for %s", returnType);
      }
    }

Retrofit的callAdapter()源码如下:

  public CallAdapter<?, ?> callAdapter(Type returnType, Annotation[] annotations) {
    return nextCallAdapter(null, returnType, annotations);
  }

  public CallAdapter<?, ?> nextCallAdapter(CallAdapter.Factory skipPast, Type returnType,
      Annotation[] annotations) {
    checkNotNull(returnType, "returnType == null");
    checkNotNull(annotations, "annotations == null");

    int start = adapterFactories.indexOf(skipPast) + 1;
    for (int i = start, count = adapterFactories.size(); i < count; i++) {
      //从链表中拿出一个CallAdapter.Factory,调用其get()方法,如果不为空,则返回。
      CallAdapter<?, ?> adapter = adapterFactories.get(i).get(returnType, annotations, this);
      if (adapter != null) {
        return adapter;
      }
    }

    StringBuilder builder = new StringBuilder("Could not locate call adapter for ")
        .append(returnType)
        .append(".\n");
    if (skipPast != null) {
      builder.append(" Skipped:");
      for (int i = 0; i < start; i++) {
        builder.append("\n * ").append(adapterFactories.get(i).getClass().getName());
      }
      builder.append('\n');
    }
    builder.append(" Tried:");
    for (int i = start, count = adapterFactories.size(); i < count; i++) {
      builder.append("\n * ").append(adapterFactories.get(i).getClass().getName());
    }
    throw new IllegalArgumentException(builder.toString());
  }

adapterFactories.get()获取的CallAdapter.Factory其实就是Retrofit的Build在调用build()方法的时候设置的。先看Platform的源码:

    static class Android extends Platform {
        @Override
        public Executor defaultCallbackExecutor() {
            return new MainThreadExecutor();
        }

        @Override
        CallAdapter.Factory defaultCallAdapterFactory(Executor callbackExecutor) {
            return new ExecutorCallAdapterFactory(callbackExecutor);//Retrofit使用的就是这个Factory
        }

        static class MainThreadExecutor implements Executor {
            private final Handler handler = new Handler(Looper.getMainLooper());

            @Override
            public void execute(Runnable r) {
                handler.post(r);
            }
        }
    }

所以adapterFactories.get()获取的就是ExecutorCallAdapterFactory。ExecutorCallAdapterFactory的get()方法源码如下:

  public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
    if (getRawType(returnType) != Call.class) {
      return null;
    }
    final Type responseType = Utils.getCallResponseType(returnType);
    return new CallAdapter<Object, Call<?>>() {
      @Override public Type responseType() {
        return responseType;
      }

      @Override public Call<Object> adapt(Call<Object> call) {
        return new ExecutorCallbackCall<>(callbackExecutor, call);
      }
    };
  }

先看if里面的判断条件,returnType的获取方式为:

method.getGenericReturnType()

Method的getGenericReturnType()返回的就是Method的返回值类型,比如:void,int,String等。而在这里代表的是文章开头描述的第二步中的接口中的方法返回值。如果不是Call的话,if会返回false,否则返回一个CallAdapter。
CallAdapter的adapt()方法返回的是一个ExecutorCallbackCall的实例。
也就是说Retrofit的create()方法的动态代理最终返回了一个ExecutorCallbackCall实例。
对应到开头的例子中,也就是

  TestApi testApi = retrofit.create(TestApi.class);//获取的是一个代理类,而不是new出来的。
  Call<ResponseBody> userCall = testApi.getTestResult("/user/renyiguang",p);//获取到的是ExecutorCallbackCall的实例。

所以在调用userCall.enqueue()方法时,其实是调用的ExecutorCallbackCall的enqueue()方法。ExecutorCallbackCall源码如下:

static final class ExecutorCallbackCall<T> implements Call<T> {
    final Executor callbackExecutor;
    final Call<T> delegate;

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

    @Override public void enqueue(final Callback<T> callback) {
      checkNotNull(callback, "callback == null");

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

    @Override public boolean isExecuted() {
      return delegate.isExecuted();
    }

    @Override public Response<T> execute() throws IOException {
      return delegate.execute();
    }

    @Override public void cancel() {
      delegate.cancel();
    }

    @Override public boolean isCanceled() {
      return delegate.isCanceled();
    }

    @SuppressWarnings("CloneDoesntCallSuperClone") // Performing deep clone.
    @Override public Call<T> clone() {
      return new ExecutorCallbackCall<>(callbackExecutor, delegate.clone());
    }

    @Override public Request request() {
      return delegate.request();
    }
  }

ExecutorCallbackCall其实是个代理类,其方法都是调用的delegate的相应方法。delegate是什么呢?是CallAdapter调用adapt()传入的参数。CallAdapter的adapt()是何时调用的呢?还是在Retrofit的create()中,传入的是OkHttpCall。
那么就看一下OkHttpCall的enqueue()方法,其源码如下:

@Override public void enqueue(final Callback<T> 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) { 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) 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(); } } }); }

这个方法可以说是retrofit真正的入口方法。先来看一下createRawCall()这个方法。

 private okhttp3.Call createRawCall() throws IOException { Request request = serviceMethod.toRequest(args);//根据输入参数返回Request。这是OkHttp的Request okhttp3.Call call = serviceMethod.callFactory.newCall(request);//根据request,返回call,这是OkHttp的call。 if (call == null) { throw new NullPointerException("Call.Factory returned null."); } return call; }

ServiceMethod的toRequest()方法实现如下:

  Request toRequest(Object... args) throws IOException {
    RequestBuilder requestBuilder = new RequestBuilder(httpMethod, baseUrl, relativeUrl, headers,
        contentType, hasBody, isFormEncoded, isMultipart);

    @SuppressWarnings("unchecked") // It is an error to invoke a method with the wrong arg types.
    ParameterHandler<Object>[] handlers = (ParameterHandler<Object>[]) parameterHandlers;

    int argumentCount = args != null ? args.length : 0;
    if (argumentCount != handlers.length) {
      throw new IllegalArgumentException("Argument count (" + argumentCount
          + ") doesn't match expected count (" + handlers.length + ")");
    }

    for (int p = 0; p < argumentCount; p++) {
      handlers[p].apply(requestBuilder, args[p]);//这里是参数参数配置的核心,具体细节下一节会专门分析
    }

    return requestBuilder.build();
  }

当拿到Okhttp的Request之后就是Okhttp的事情了。

你可能感兴趣的:(retrofit2源码分析)