Retrofit源码解析

635 阅读7分钟
原文链接: blog.csdn.net

retrofit源码解析

在近期的项目中网络框架使用retrofit居多,总而言之retrofit的使用还是比较熟练的,从封装到网络请求的bindData,还是比较方便的;retrofit的注解和retrofit+rajava是的retrofit成为android网络框架的主流
下面看一张图:
这里写图片描述

下面代码为retrofit的简单使用:<包括添加了retrofit请求的对话框>

 private ApiClient(Context context) {
        this.mContext = context;
        initHttpClient();
        mRetrofit = new Retrofit.Builder()
                .baseUrl(Constant.BASE_URL)//设置baseurl参数
                .client(mOkHttpClient)//设置OkHttpClient实例
                .addConverterFactory(GsonConverterFactory.create())//gson转化工厂
                .build();
    }

    /**
     * 公有的方法创建ApiClients对象
     * @return
     */
    public static ApiClient getInstance(Context context) {
        if (mApiClient == null) {
            synchronized (ApiClient.class) {
                mApiClient = new ApiClient(context);
            }
        }
        return mApiClient;
    }

    /**
     * 关联接口定义类
     */
    public <T> T create(Class<T> service) {
        return mRetrofit.create(service);
    }

    /**
     * 二次封装回调接口
     * @param call
     * @param mCallBack
     * @param <T>
     */
    public <T> void show(Call<T> call, final boolean isLoading,final RetrofitListener<T> mCallBack) {

        //展示对话框
        mCallBack.onBefor(isLoading);

        call.enqueue(new Callback<T>() {
            @Override
            public void onResponse(Call<T> call, retrofit2.Response<T> response) {
                mCallBack.onAfter(isLoading);
                mCallBack.onResponse(call, response);
            }

            @Override
            public void onFailure(Call<T> call, Throwable t) {
                mCallBack.onAfter(isLoading);
                mCallBack.onFailure(call, t);
            }
        });
    }

retrofit的大概流程:第一步,创建一个接口。第二步,创建一个Retrofit对象,提供BASE_URL等信息。第三步,创建一个实现了接口的代理对象。第四步,调用接口方法,返回一个Call对象。第五步,调用execute执行同步请求。第六步,从响应获取数据。进行数据的bind。

ok~ 开始看retrofit的源码:

1

//new Retrofit.Builder() 先来看Builder类

public static final class Builder {
    ...
    Builder(Platform platform) {
      this.platform = platform;
      converterFactories.add(new BuiltInConverters());
    }

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

    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;
    }
    public Builder baseUrl(String baseUrl) {
      checkNotNull(baseUrl, "baseUrl == null");
      HttpUrl httpUrl = HttpUrl.parse(baseUrl);
      if (httpUrl == null) {
        throw new IllegalArgumentException("Illegal URL: " + baseUrl);
      }
      return baseUrl(httpUrl);
    }

    public Builder baseUrl(HttpUrl baseUrl) {
      checkNotNull(baseUrl, "baseUrl == null");
      List<String> pathSegments = baseUrl.pathSegments();
      if (!"".equals(pathSegments.get(pathSegments.size() - 1))) {
        throw new IllegalArgumentException("baseUrl must end in /: " + baseUrl);
      }
      this.baseUrl = baseUrl;
      return this;
    }

    public Builder addConverterFactory(Converter.Factory factory) {
      converterFactories.add(checkNotNull(factory, "factory == null"));
      return this;
    }

    public Builder addCallAdapterFactory(CallAdapter.Factory factory) {
      adapterFactories.add(checkNotNull(factory, "factory == null"));
      return this;
    }

    public Builder callbackExecutor(Executor executor) {
      this.callbackExecutor = checkNotNull(executor, "executor == null");
      return this;
    }

    public Builder validateEagerly(boolean validateEagerly) {
      this.validateEagerly = validateEagerly;
      return this;
    }

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

      List<CallAdapter.Factory> adapterFactories = new ArrayList<>(this.adapterFactories);
      adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));

      List<Converter.Factory> converterFactories = new ArrayList<>(this.converterFactories);

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

1.new Retrofit.Builder()是获取平台信息,并且将内置的转换工厂加入当工厂集合中去 2:从我们的基本示例中看到有调用到.baseUrl(BASE_URL)这个方法,实际上没当使用Retrofit时,该方法都是必须传入的,并且还不能为空,从源码中可以看出,当baseUrl方法传进的参数来看,如果为空的话将会抛出NullPointerException空指针异常。

3:addConverterFactory该方法是传入一个转换器工厂,它主要是对数据转化用的,请网络请求获取的数据,将会在这里被转化成我们所需要的数据类型,比如通过Gson将json数据转化成对象类型。

4 : 从源码中,我们看到还有一个client方法,这个是可选的,如果没有传入则就默认为OkHttpClient,在这里可以对OkHttpClient做一些操作,比如添加拦截器打印log等

5:callbackExecutor该方法从名字上看可以得知应该是回调执行者,也就是Call对象从网络服务获取数据之后转换到UI主线程中。

6:addCallAdapterFactory该方法主要是针对Call转换了,比如对Rxjava的支持,从返回的call对象转化为Observable对象。

7:最后调用build()方法,通过new Retrofit(callFactory, baseUrl, converterFactories, adapterFactories,callbackExecutor, validateEagerly);构造方法把所需要的对象传递到Retrofit对象中。

2.

//mRetrofit.create(xxxApi.class//即注解类)

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, @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);
            }
            ServiceMethod<Object, Object> serviceMethod =
                (ServiceMethod<Object, Object>) loadServiceMethod(method);
            OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
            return serviceMethod.callAdapter.adapt(okHttpCall);
          }
        });
  }

首先xxxApi api = mRetrofit.create(xxxApi.class//即注解类)返回的是一个动态代理对象(动态代理之后单独详解)api,之后用动态代理对象调用注解类中方法,获取request:

Call<AppointInfo> appointInfo = responseInfoApi.getAppointInfo("APPAPI","123456", code, data);

在这里responseInfoApi.getAppointInfo(“APPAPI”,”123456”, code, data);走的是Proxy.newProxyInstance中的invoke方法,相当于动态拦截,进而调用; 当然最核心代码就是:

 ServiceMethod serviceMethod = loadServiceMethod(method);
 OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);
 return serviceMethod.callAdapter.adapt(okHttpCall);

通过method获取serviceMethod对象—->再次获取okHttpCall对象,通过serviceMethod.callAdapter.adapt 继续封装okHttpCall 返回call对象,即request对象 下面看loadServiceMethod:

ServiceMethod loadServiceMethod(Method method) {
    ServiceMethod result;
    synchronized (serviceMethodCache) {
      result = serviceMethodCache.get(method);
      if (result == null) {
        result = new ServiceMethod.Builder(this, method).build();
        serviceMethodCache.put(method, result);
      }
    }
    return result;
  }

其实在loadServiceMethod中有一个serviceMethodCache即serviceMethod的一个缓存队列,首先通过method从缓存队列中获取相应的serviceMethod,若为空,通过new ServiceMethod.Builder(this, method).build();得到serviceMethod,并且serviceMethodCache.put(method, result); 然后看new ServiceMethod.Builder(this, method).build()源码

public Builder(Retrofit retrofit, Method method) {
      this.retrofit = retrofit;
      this.method = method;
      this.methodAnnotations = method.getAnnotations();
      this.parameterTypes = method.getGenericParameterTypes();
      this.parameterAnnotationsArray = method.getParameterAnnotations();
    }

public ServiceMethod build() {
      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?");
      }
      responseConverter = createResponseConverter();
      ...
      return new ServiceMethod<>(this);
    }

可以看的出来,在builder中初始化一部分参数,在build中返回serviceMethod; 接着着眼看build方法,//createCallAdapter();

private CallAdapter<?> 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 {
        return retrofit.callAdapter(returnType, annotations);
      } catch (RuntimeException e) { // Wide exception range because factories are user code.
        throw methodError(e, "Unable to create call adapter for %s", returnType);
      }
    }

build就是获取method的类型以及注解:

Type returnType = method.getGenericReturnType();

然后调用retrofit.callAdapter(returnType, annotations);

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<?> adapter = adapterFactories.get(i).get(returnType, annotations, this);
      if (adapter != null) {
        return adapter;
      }
    }
    ...
}

最后调用nextCallAdapter,for遍历adapterFractory,获取callAdapter对象,那么下面从builder构造器中获取callAdapter对象:

public static final class Builder {
    ...
    public Builder addCallAdapterFactory(CallAdapter.Factory factory) {
      adapterFactories.add(checkNotNull(factory, "factory == null"));
      return this;
    }
    ...
    public Retrofit build() {
      List<CallAdapter.Factory> adapterFactories = new ArrayList<>(this.adapterFactories);
      adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));
    ...
    }  
  }

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

//通过serviceMethod, args获取到okHttpCall 对象第二步相对比较简单,就是对象传递:

OkHttpCall(ServiceMethod<T> serviceMethod, Object[] args) {
    this.serviceMethod = serviceMethod;
    this.args = args;
  }

//serviceMethod.callAdapter.adapt(okHttpCall),获取okHttpCall对象之后,对其进行封装成call对象,作为request进行请求,查看adapt源码

 T adapt(Call<R> call);

很简单的一句,没有头绪有木有,那么 接着看serviceMethod.callAdapter:

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

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

return new ExecutorCallbackCall<>(callbackExecutor, call);就是上面那句奇怪的代码;那么这样就获得了call对象 可以开始下一步请求了;

3.

请求方式分为同步和异步,这里以异步为例<一般都使用异步>,// call.enqueue(new Callback() ,具体实现如下:

service.enqueue(new Callback<List<User>>() {
    @Override
    public void onResponse(Call<List<User>> call, Response<List<User>> response) {
        Log.d("response body",response.body());
    }

    @Override
    public void onFailure(Call<BoardInfo> call, Throwable t) {
        Log.i("response Throwable",t.getMessage().toString());
    }
});

从上面的代理获取拦截可以看出Call对象就是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) {
      if (callback == null) throw new NullPointerException("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()) {
                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);
            }
          });
        }
      });
    }

由上代码可以看出,在ExecutorCallbackCall中定义了两个接口

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

其中callbackExecutor 是完成线程的切换,而delegate是执行异步请求的主体

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

接下来看delegate 如何执行异步请求:

@Override 
public void enqueue(final Callback<T> callback) {
    if (callback == null) throw new NullPointerException("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();
        }
      }
    });
  }

其实不难看出就是okhttp的封装了~ 到这里就结束了 有什么不清楚的可以继续研究源码.