Retrofit源码分析

来源:互联网 发布:淘宝隐形眼镜可以买吗 编辑:程序博客网 时间:2024/05/17 21:13

关于Retrofit,网上有很多源码分析,感觉好多都是泛泛而谈,当然好文章也有几篇,怀揣着瑟瑟发抖的心,我也走进了Retrofit源码的大门。。。。。

Retrofit retrofit = new Retrofit.Builder()        .addConverterFactory(GsonConverterFactory.create())        .baseUrl(API_URL)        .build();

首先,创建一个Retrofit对象,咱们一个方法一个方法的去看。首先看new Retrofit.Builder():

Builder(Platform platform) {  this.platform = platform;  // 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());}public Builder() {  this(Platform.get());}

Platfrom.get() ?????  这是啥玩意?那我们来看Platform类:

private static final Platform PLATFORM = findPlatform();static Platform get() {  return PLATFORM;}
private static Platform findPlatform() {  try {    Class.forName("android.os.Build");    if (Build.VERSION.SDK_INT != 0) {      return new Android();    }  } catch (ClassNotFoundException ignored) {  }  //省略n行代码。。。。。  return new Platform();}
static class Android extends Platform {  @Override public Executor defaultCallbackExecutor() {    return new MainThreadExecutor();  }  @Override CallAdapter.Factory defaultCallAdapterFactory(Executor callbackExecutor) {    return new ExecutorCallAdapterFactory(callbackExecutor);  }  static class MainThreadExecutor implements Executor {    private final Handler handler = new Handler(Looper.getMainLooper());    @Override public void execute(Runnable r) {      handler.post(r);    }  }}
Android这个类继承了Platform, 类中重写了两个方法,第一个方法defaultCallbackExecutor(),return 了一个MainThreadExecutor对象,我们一眼就看出来了这个对象是干嘛的了,将消息发送给主线程,那肯定是刷新UI了。第二个方法先不管,等用到的时候再说。

再回到Retrofit类中,我们的得到:this.platform = new Android();

converterFactories.add(new BuiltInConverters());
这个方法,看字面的意思,加入一个转换器,我们进入到BuiltInConverters中,确实也是这么回事,转换request,response,url的格式,先跳过这块,如果有时间我们再做分析。

Builder()分析完了,来看:

addConverterFactory(GsonConverterFactory.create())
这个不多说了,将GsonConverterFactory也加入到咱们转换工厂的List中

.baseUrl(API_URL)
设置咱们的访问域名

最后一个方法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();  }  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);}
callFactory = new OkHttpClient(), 哦,原来Retrofit网络请求部分用的也是OkHttpClient,但是我们也能看出来我们可以自定义callFactory

platfrom.defaultCallbackEXecutor(); 刚才咱们分析过了,返回的是一个Executor, 这是retrofit默认给我提供的处理方式;如果我们在RxJava就不一样了

adapterFactories处理线程关系的list, 可以看到这个将callbackExecutor放到了defaultCallAdapterFactory中。

最后返回Retrofit对象。

ZhuanLanApi api = retrofit.create(ZhuanLanApi.class);
我们进入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) {            return method.invoke(this, args);          }          if (platform.isDefaultMethod(method)) {            return platform.invokeDefaultMethod(method, service, proxy, args);          }          ServiceMethod serviceMethod = loadServiceMethod(method);          OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);          return serviceMethod.callAdapter.adapt(okHttpCall);        }      });}
使用了动态代理

if (method.getDeclaringClass() == Object.class) {  return method.invoke(this, args);}
这个方法当时我觉得很奇怪,后来仔细琢磨一下,这个方法主要提供兼容用户调用hashCode等Object方法,看到这里,很感叹,作为一个成熟的网络框架,那么多人去

使用,细节很关键。

if (platform.isDefaultMethod(method)) {  return platform.invokeDefaultMethod(method, service, proxy, args);}
这个判断不用管,Android类中没有重写isDefaultMethod方法,始终返回false

ServiceMethod serviceMethod = loadServiceMethod(method);
去创建ServiceMethod对象

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;}
这里巧妙的用了一个缓存,重点是build()方法:

public ServiceMethod build() {  callAdapter = createCallAdapter();  responseType = callAdapter.responseType();  //省略n行代码。。。  responseConverter = createResponseConverter();  for (Annotation annotation : methodAnnotations) {    parseMethodAnnotation(annotation);  }  //省略n行代码。。。  int parameterCount = parameterAnnotationsArray.length;  parameterHandlers = new ParameterHandler<?>[parameterCount];  for (int p = 0; p < parameterCount; p++) {    Type parameterType = parameterTypes[p];    if (Utils.hasUnresolvableType(parameterType)) {      throw parameterError(p, "Parameter type must not include a type variable or wildcard: %s",          parameterType);    }    Annotation[] parameterAnnotations = parameterAnnotationsArray[p];    if (parameterAnnotations == null) {      throw parameterError(p, "No Retrofit annotation found.");    }    parameterHandlers[p] = parseParameter(p, parameterType, parameterAnnotations);  }  //省略n行代码。。。  return new ServiceMethod<>(this);}
  callAdapter = createCallAdapter();
进入createCallAdapter方法:

private CallAdapter<?> createCallAdapter() {  Type returnType = method.getGenericReturnType();  //省略n行  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);  }}

 method.getGenericReturnType()
得到返回值类型(带泛型)

Annotation[] annotations = method.getAnnotations();
得到方法的所有注解

retrofit.callAdapter方法中跳转到nextCallAdapter,所以我们直接来看nextCallAdapter方法

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;    }  }  //省略n行。。。}
CallAdapter<?> adapter = adapterFactories.get(i).get(returnType, annotations, this);
还记得我们向adapterFactories集合中存过ExecutorCallAdapterFactory对象,这段代码就是把它取出来,get()方法:

@Overridepublic 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);    }  };}
返回了一个Call对象,responseType方法返回的是方法的泛型类型, 

adapt返回的是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()) {              // 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);          }        });      }    });  }
  //省略n行代码。。。。
}
这个对象中包含enqueue方法,看到这里,相信你已经明白了。。。

现在我们继续回到ServiceMethod中build()方法中:

responseType = callAdapter.responseType();
这个刚才说过了。。

responseConverter = createResponseConverter();
这里和adapterFactory一样的逻辑,就不提了。。。

for (Annotation annotation : methodAnnotations) {  parseMethodAnnotation(annotation);}
根据注解,来判断是什么请求。。。代码我就不贴了

return new ServiceMethod<>(this);
最后将ServiceMethod对象返回。。。

OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);return serviceMethod.callAdapter.adapt(okHttpCall);
最后调用ExecutorCallbackCall对象的adapt方法

Call<text> call = api.getAuthor("1", "1");
这时候就可以传参数请求网络了。。。。

大概的流程就是这样的,当然有很多细节,包括反射啊,注解啊等等。。。要说起来太多了,我觉得Retrofit是一个非常好的网络请求框架,它把工厂模式用淋漓极致,扩展性非常好。。



0 0