概述

Retrofit适用于Android和Java的类型安全的HTTP客户端。一个RESTful的基于OKHttp的Http网络框架。简单网络请求,提高开发效率。

使用如下

  1. 定义Java接口
public interface GitHubService {
  @GET("users/{user}/repos")
  Call<List<Repo>> listRepos(@Path("user") String user);
}
  1. 构建Retrofit对象
Retrofit retrofit = new Retrofit.Builder()
    .baseUrl("https://api.github.com/")
    .build();
  1. 生成Java接口对象
GitHubService service = retrofit.create(GitHubService.class);
  1. 调用对象的方法获取对应的Call
Call<List<Repo>> repos = service.listRepos("octocat");
  1. 也就是调用Callexecute方法进行同步网络请求,或者调用enqueue进行异步的网路请求。

接下来我们会根据一一分析这5个步骤。基于Retrofit2.4.0分析。

Java接口定义

由于Retrofit使用的动态代理进行生成接口对象的,我们的网络请求的接口必须是Java接口。

Retrofit定义了许多的注解。定义网络请求的接口就是通过这些注解来完成的。

Retrofit源码解析

注解会保留到运行时,因为Retrofit需要根据这些注解去解析运行时的参数。

比如GET注解

@Documented
@Target(METHOD)
@Retention(RUNTIME)
public @interface GET {
  String value() default "";
}

GET方法上的注解,注解保留到运行时。

构建Retrofit对象

Retrofit源码解析

使用了Builder模式来创建Retrofit对象。Retrofit.Builder拥有很多创建Retrofit的配置项,通过这些配置项来创建Retrofit对象。每个配置项的方法返回Builder对象,用于.来进行配置的连接,最后通过build方法创建Retrofit

比如配置baseUrl

public static final class Builder {
    public Builder baseUrl(String baseUrl) {
      checkNotNull(baseUrl, "baseUrl == null");
      return baseUrl(HttpUrl.get(baseUrl));
    }

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

检测baseUrl是否为null,调用重载的baseUrl方法。baseUrl(HttpUrl baseUrl)中检测baseUrl是否为null,并且检测url是否合法,最后赋值给Builder对象的baseUrl。最后返回this

build方法:

public static final class Builder {
    public Retrofit build() {
      if (baseUrl == null) {
        throw new IllegalStateException("Base URL required.");
      }
	  ......
      return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories),
          unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);
    }
}

通过此方法返回Retrofit对象。

这里先不进行配置项相关的说明,后面碰到会说明。

生成Java接口对象

Retrofit源码解析

获取接口对象时,是通过Retrofitcreate方法。

public final class Retrofit {
    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();
          		private final Object[] emptyArgs = new Object[0];
          		@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.adapt(okHttpCall);
          		}
        	});
  	}
}

首先调用Utils.validateServiceInterface方法验证service

final class Utils {
    static <T> void validateServiceInterface(Class<T> service) {
    	if (!service.isInterface()) {
	    	throw new IllegalArgumentException("API declarations must be interfaces.");
    	}
    	if (service.getInterfaces().length > 0) {
      		throw new IllegalArgumentException("API interfaces must not extend other interfaces.");
    	}
  	}
}

此方法验证service是不是Java接口,并且验证接口是否继承了其他接口。

接着分析Retrofitcreate的方法。通过变量validateEagerly来判断是否调用eagerlyValidateMethods方法,validateEagerly表示是否调用create方法时急切的验证接口中的方法的配置,默认是false

接着是创建一个InvocationHandler匿名内部类对象,调用Proxy.newProxyInstance的方法来创建一个Java接口对象。这里使用了Java的动态代理的知识。一旦调用Java接口中的方法就会调用到InvocationHandler中的invoke方法。

总结:

Retrofit的create方法有两个功能,一是验证接口,一个是通过Proxy.newProxyInstance方法生成一个动态代理的Java接口对象。

调用对象的方法获取Call

Retrofit源码解析

调用对象的方法会调用到InvocationHandler匿名对象的invoke方法。

Call<List<Repo>> repos = service.listRepos("octocat");

我们来分析一下InvocationHandler匿名内部对象的invoke方法。

public final class Retrofit {
    public <T> T create(final Class<T> 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 Object invoke(Object proxy, Method method,
                                               @Nullable Object[] args) throws Throwable {
            		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.adapt(okHttpCall);
          	}
        });
  	}
}

invoke有三个参数,proxy是调用者对象,method调用的方法,args调用方法的参数。

首先调用methodgetDeclaringClass获取声明类是不是Object,也就是判断是不是Object的方法,如果是直接调用方法。

然后调用Platform对象的isDefaultMethod。what?Platform什么?????先放一下。后面我们在分析。

最后是调用RetrofitloadServiceMethod获取ServiceMethod对象,并且创建一个OkHttpCall对象,并调用OkHttpCall适配返回。

我们先来分析一下Platform

Platform

Retrofit源码解析

因为Retrofit支持Java平台和Android平台,而Platform就是对平台的抽象。使用单例设计模式。

class Platform {
  	private static final Platform PLATFORM = findPlatform();

  	static Platform get() {
    	return PLATFORM;
  	}
    ......
}

使用的是饿汉式的单例设计方式。获取具体实现的对象是通过findPlatform方法。

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

通过Class.formName获取相关的类,获取不到就会报异常,Android平台检测的是android.os.Build类,存在并且SDK的版本不等于0就返回Android

Android类中的isDefault方法

static class Android extends Platform {
  	@Override boolean isDefaultMethod(Method method) {
    	if (Build.VERSION.SDK_INT < 24) {
      		return false;
    	}
    	return method.isDefault();
  	}
    ......
}

小于24版本直接返回false。大于等于24是调用的methodisDefaultisDefault是接口类型中定义的非静态非抽象的方法。

Notice:

Platform中有许多的默认配置。在创建Retrofit时,在Builder中也使用到了Platoform

上面分析到了InvocationHandler的方法中

if (platform.isDefaultMethod(method)) {
	return platform.invokeDefaultMethod(method, service, proxy, args);
}

不满足因此会调用RetrofitloadServiceMethod方法。

Retrofit的loadServiceMethod方法

public final class Retrofit {
    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) {
        		result = new ServiceMethod.Builder<>(this, method).build();
        		serviceMethodCache.put(method, result);
      		}
    	}
    	return result;
  	}
}

这里采用了双重检测。首先从缓存的Map获取ServiceMethod,第一次调用时是没有缓存的。然后进入synchronized块中再检测一次,如果还是不存在就使用ServiceMethod.Builder来创建ServiceMethod方法。然后放入缓存中。

ServiceMethod是一个很关键的类,所有的解析都在这里面呢。我接着分析ServiceMethod`类。

ServiceMethod

ServiceMethod也是通过Builder模式来创建的。只是很奇怪既然是Builder模式但是只有一个build方法,确没有相关的配置方法,未免有点鸡肋了。

static final class Builder<T, R> {
    final Retrofit retrofit;
    final Method method;
    final Annotation[] methodAnnotations;
    final Annotation[][] parameterAnnotationsArray;
    final Type[] parameterTypes;
 	Builder(Retrofit retrofit, Method method) {
  		this.retrofit = retrofit;
  		this.method = method;
  		this.methodAnnotations = method.getAnnotations();
  		this.parameterTypes = method.getGenericParameterTypes();
  		this.parameterAnnotationsArray = method.getParameterAnnotations();
	}   
}

Builder的构造方法中,关键是通过method获取方法的注解,获取参数的注解,以及参数的类型。

我们接着分析Builderbuild方法。

Retrofit源码解析

ServiceMethodBuilderbuild方法主要有五个步骤

  1. 调用createCallAdapter方法创建CallAdapter,用于适配OkHttp中的Call
  2. 调用createResponseConverter方法创建Converter<ResponseBody, T>对象,用于转换ResponseBody到相应的对象。
  3. 循环调用parseMethodAnnotation方法来解析方法的注解
  4. 循环调用parseParameter方法解析方法的参数注解
  5. 创建ServiceMethod对象

我们一步一步分析其功能。

获取CallAdapter对象

第一步是调用createCallAdapter方法来获取CallAdapter对象

static final class Builder<T, R> {
    CallAdapter<T, R> callAdapter;
 	public ServiceMethod build() {
  		callAdapter = createCallAdapter();
        ......
	}   
}

通过createCallAdapter来获取callAdapter对象。

static final class Builder<T, R> {
    CallAdapter<T, R> callAdapter;
 	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);
      } catch (RuntimeException e) { // Wide exception range because factories are user code.
        throw methodError(e, "Unable to create call adapter for %s", returnType);
      }
    }
}

首先解析method的返回的类型,判断是否可以解析。然后获取方法的注解,并调用retrofit对象的callAdapter方法获取对象。

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

会调用RetrofitnextCallAdapter方法。

public final class Retrofit { 
      final List<CallAdapter.Factory> callAdapterFactories;
      public CallAdapter<?, ?> nextCallAdapter(
          @Nullable CallAdapter.Factory skipPast, Type returnType, Annotation[] annotations) {
    	checkNotNull(returnType, "returnType == null");
    	checkNotNull(annotations, "annotations == null");

    	int start = callAdapterFactories.indexOf(skipPast) + 1;
    	for (int i = start, count = callAdapterFactories.size(); i < count; i++) {
      		CallAdapter<?, ?> adapter = 
                callAdapterFactories.get(i).get(returnType, annotations, this);
      		if (adapter != null) {
        		return adapter;
      		}
    	}
        ......
  	}
}

检测返回着类型,和方法的注解。传递的skipPasenull,因此遍历所有的callAdapterFactories通过get方法来获取到CallAdapter对象。

callAdapterFactories是在Retrofit.Builder中进行赋值的。在Builder中有两个地方进行添加的,一个是在

public static final class Builder {
    public Builder addCallAdapterFactory(CallAdapter.Factory factory) {
      callAdapterFactories.add(checkNotNull(factory, "factory == null"));
      return this;
    }
    public Retrofit build() {
      ......
      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> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
      callAdapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));
    }
}

第一个是通过addCallAdapter.Factory添加自己的CallAdapterFactory,第二个是通过获取通过platform获取Executor对象。然后通过defaultCallAdapterFactory获取CallAdapter.Factory对象。

我们分析平台为Android我们来看一下这两个函数返回什么内容。

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

  @Override CallAdapter.Factory defaultCallAdapterFactory(@Nullable Executor callbackExecutor) {
    if (callbackExecutor == null) throw new AssertionError();
    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);
    }
  }
}

defaultCallbackExecutor返回的是主线程的Executor封装。defaultCallAdapterFactory返回的是ExecutorCallAdapterFactory

final class ExecutorCallAdapterFactory extends CallAdapter.Factory {
  final Executor callbackExecutor;

  ExecutorCallAdapterFactory(Executor callbackExecutor) {
    this.callbackExecutor = callbackExecutor;
  }

  @Override
  public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
    ......
    return new CallAdapter<Object, Call<?>>() {
      @Override public Type responseType() {
        return responseType;
      }

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

ExecutorCallAdapterFactoryget方法中获取的CallAdapter对象,关键的是复写了adapte返回ExecutorCallbackCall

Converter对象

第二步是在createResponseConverter来获取Converter对象。

static final class Builder<T, R> {
    final List<CallAdapter.Factory> callAdapterFactories;
    private Converter<ResponseBody, T> createResponseConverter() {
      Annotation[] annotations = method.getAnnotations();
      try {
        return retrofit.responseBodyConverter(responseType, annotations);
      } catch (RuntimeException e) { // Wide exception range because factories are user code.
        throw methodError(e, "Unable to create converter for %s", responseType);
      }
    }
}

此方法会调用RetrofitresponseBodyConverter获取Converter对象。

public final class Retrofit {
    public <T> Converter<ResponseBody, T> responseBodyConverter(
        Type type, Annotation[] annotations) {
    	return nextResponseBodyConverter(null, type, annotations);
  	}
}

会调用RetrofitnextCallAdapter方法。

public final class Retrofit {
    public <T> Converter<ResponseBody, T> nextResponseBodyConverter(
      @Nullable Converter.Factory skipPast, Type type, Annotation[] annotations) {
    checkNotNull(type, "type == null");
    checkNotNull(annotations, "annotations == null");

    int start = converterFactories.indexOf(skipPast) + 1;
    for (int i = start, count = converterFactories.size(); i < count; i++) {
      Converter<ResponseBody, ?> converter =
          converterFactories.get(i).responseBodyConverter(type, annotations, this);
      if (converter != null) {
        //noinspection unchecked
        return (Converter<ResponseBody, T>) converter;
      }
    }
    ......
  }
}

检测方法的类型,检测方法的注解。我们传递的skipPastnull,因此循环converterFactories集合然后调用FactoryresponseBodyConverter方法。最后返回判断是否遍历到了。

循环解析方法注解

第三步是循环调用parseMethodAnnotation方法解析注解。

static final class Builder<T, R> {
    public ServiceMethod build() {
      for (Annotation annotation : methodAnnotations) {
        parseMethodAnnotation(annotation);
      }
    }
}

我们现在来分析一下parseMethodAnnotation方法。

static final class Builder<T, R> {
     private void parseMethodAnnotation(Annotation annotation) {
      if (annotation instanceof DELETE) {
        parseHttpMethodAndPath("DELETE", ((DELETE) annotation).value(), false);
      } else if (annotation instanceof GET) {
        parseHttpMethodAndPath("GET", ((GET) annotation).value(), false);
      } else if (annotation instanceof HEAD) {
        parseHttpMethodAndPath("HEAD", ((HEAD) annotation).value(), false);
        if (!Void.class.equals(responseType)) {
          throw methodError("HEAD method must use Void as response type.");
        }
      }
      ......
    }
}

根据注解的类型进行相关的解析。限于篇幅的解析我们这里就不展开了。

解析方法参数注解

第四步是循环调用parseParameter来处理参数。

static final class Builder<T, R> {
    public ServiceMethod build() {
        int parameterCount = parameterAnnotationsArray.length;
        //创建ParameterHandler数组
      	parameterHandlers = new ParameterHandler<?>[parameterCount];
        for (int p = 0; p < parameterCount; p++) {
        	Type parameterType = parameterTypes[p];
        	......
        	parameterHandlers[p] = parseParameter(p, parameterType, parameterAnnotations);
      }
    }
}

for循环中进行了很多判断我们这里省略。我们继续分析parseParameter方法。

static final class Builder<T, R> {
     private ParameterHandler<?> parseParameter(
        int p, Type parameterType, Annotation[] annotations) {
      ParameterHandler<?> result = null;
      for (Annotation annotation : annotations) {
        ParameterHandler<?> annotationAction = parseParameterAnnotation(
            p, parameterType, annotations, annotation);

        if (annotationAction == null) {
          continue;
        }

        if (result != null) {
          throw parameterError(p, "Multiple Retrofit annotations found, only one allowed.");
        }

        result = annotationAction;
      }

      if (result == null) {
        throw parameterError(p, "No Retrofit annotation found.");
      }

      return result;
    }
}

每个参数可以包含多个注解,这里循环调用parseParameterAnnotation进行解析。

static final class Builder<T, R> {
   private ParameterHandler<?> parseParameterAnnotation(
        	int p, Type type, Annotation[] annotations, Annotation annotation) {
      if (annotation instanceof Url) {
        ......
        return new ParameterHandler.RelativeUrl();
	    ......
      } else if (annotation instanceof Path) {
        return new ParameterHandler.Path<>(name, converter, path.encoded());
      }
   }
}

parseParameterAnnotation中的结构基本就是判断是否不是某个注解,然后返回相应的ParameterHandler中的类。

我们来看一下ParamterHandler的继承关系。

Retrofit源码解析

每个参数注解都会继承自ParameterHandler,用于处理参数。ParameterHandler关键方法是apply会设置相应的RequestBuilder的相应的网络参数。限于类过多这里只是列举了三个。

创建ServiceMethod对象

第五步就简单了。直接创建了

static final class Builder<T, R> {
    public ServiceMethod build() {
        ......
    	return new ServiceMethod<>(this);
    }
}

传递Builder对象来创建ServiceMethod对象。

创建OKHttpCall对象

public final class Retrofit {
    public <T> T create(final Class<T> 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 Object invoke(Object proxy, Method method,
                                               @Nullable Object[] args) throws Throwable {
            		......
            		ServiceMethod<Object, Object> serviceMethod =
                			(ServiceMethod<Object, Object>) loadServiceMethod(method);
            		OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
            		return serviceMethod.adapt(okHttpCall);
          	}
        });
  	}
}

我们已经分析了如何获取ServiceMethod对象。下面我们来看看如何创建OKhttpCall的,以及如何ServiceMethod如何适配OKHttpCall对象的。

final class OkHttpCall<T> implements Call<T> {
  OkHttpCall(ServiceMethod<T, ?> serviceMethod, @Nullable Object[] args) {
    this.serviceMethod = serviceMethod;
    this.args = args;
  }
}

OkHttpCall继承自RetrofitCall接口,构造方法只是简单的赋值,serviceMethod变量为获取的ServiceMethodargs是方法的参数。

我们继续分析一下ServiceMethodadapter方法。

final class ServiceMethod<R, T> {
	T adapt(Call<R> call) {
    	return callAdapter.adapt(call);
  	}
}

仅仅通过ServiceMethodcallAdapter适配。我们在获取CallAdapter对象一节adapt方法中封装CallExecutorCallbackCall

通过Call进行网络请求

Call请求的基本流程

Retrofit源码解析

Call请求很复杂,但是基本都是简单的逻辑处理。我们一起来分析一下。

我们在调用对象的方法获取Call一节知道了Call返回的是ExecutorCallbackCall的对象,而ExecutorCallbackCall委托类是OkHttpCall

我们从ExecutorCallbackCall开始。

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

  @Override public void enqueue(final Callback<T> callback) {
    delegate.enqueue(new Callback<T>() {
      @Override public void onResponse(Call<T> call, final Response<T> response) {
        callbackExecutor.execute(new Runnable() {
          @Override public void run() {
              ......
          }
        });
      }
      ......
    });
  }
}

enqueue方法中很简单,创建一个匿名的Callback内部类,内部类会调用callbackExecutorcallbackExecutor实际为Android类中的defaultCallbackExecutor方法返回的MainThreadExecutor对象(未在Retrofit.Builder设置的情况)。也就会把结果通知到主线程。

delegate对象实际是OkHttpCall对象,我们来分析一下OkHttpCallenqueue方法。

OKHttpCall的主要功能有两个

  • 创建okhttp3.Call,用于进行真实的网络请求。
  • 调用okhttp3.Call的enqueue方法,然后对响应进行解析。

我们来一步一步进行解析。

final class OkHttpCall<T> implements Call<T> {
    private @Nullable okhttp3.Call rawCall;
    @Override public void enqueue(final Callback<T> callback) {
    	......

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

先判断executed是否已经执行过,执行过就抛出异常。

赋值rawCallcall,因为我们还没创建okhttp3.Call,因此为空,然后是尝试调动createRawCall

我们来分析一下createRawCall方法。

final class OkHttpCall<T> implements Call<T> {
    private okhttp3.Call createRawCall() throws IOException {
        okhttp3.Call call = serviceMethod.toCall(args);
    	if (call == null) {
      		throw new NullPointerException("Call.Factory returned null.");
    	}
    	return call;
  }
}

调用ServiceMethod对象的toCall方法来获取okhttp3.Call

final class ServiceMethod<R, T> {
    okhttp3.Call toCall(@Nullable Object... args) throws IOException {
    	RequestBuilder requestBuilder = 
    		new RequestBuilder(httpMethod, baseUrl, relativeUrl, headers,
        		contentType, hasBody, isFormEncoded, isMultipart);

    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 callFactory.newCall(requestBuilder.build());
  }
}

创建一个RequestBuilder对象,然后比较参数的数量是否与参数处理器(ParameterHandler)的数量一致。不一致直接抛出异常。然后是循环调用ParameterHandler的apply来构建参数。

最后调用requestBuilderbuild创建一个Request。并调用CallFactorynewCall来创一个okhttp3.Call并返回。okhttp3.Call.Factory可以通过RetrofitBuilder的下面的两个方法来定义自己的Factory

public static final class Builder {
    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;
    }
}

至此我们创建了一个okhttp3.Call对象,

下面我们是进行网络请求。

final class OkHttpCall<T> implements Call<T> {
    private @Nullable okhttp3.Call rawCall;
    @Override public void enqueue(final Callback<T> callback) {
    	......
         call.enqueue(new okhttp3.Callback() {
      		@Override public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse) {
        		Response<T> response;
        		try {
          			response = parseResponse(rawResponse);
        		} catch (Throwable e) {
          			callFailure(e);
          		return;
        	}

        	try {
          		callback.onResponse(OkHttpCall.this, response);
        	} catch (Throwable t) {
          		t.printStackTrace();
        	}
      }
      ......
    }
}

这里只列举类onResponse方法,没有列举出来onFailure方法。

在通过parseResponse来结果,根据结果调用相应的回调。我们一起来分析一下parseResponse方法

final class OkHttpCall<T> implements Call<T> {
    Response<T> parseResponse(okhttp3.Response rawResponse) throws IOException {
    	ResponseBody rawBody = rawResponse.body();
    	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();
      	}
    }
    ......
}

先获取code,判断是否是请求失败的错误码,如果是直接调用Response.error返回。

final class OkHttpCall<T> implements Call<T> { 
	Response<T> parseResponse(okhttp3.Response rawResponse) throws IOException {
    	......
		if (code == 204 || code == 205) {
      		rawBody.close();
      		return Response.success(null, rawResponse);
    	}
	    ......
    }
}

如果是204和205错误码直接返回。

final class OkHttpCall<T> implements Call<T> { 
	Response<T> parseResponse(okhttp3.Response rawResponse) throws IOException {
    	......
         ExceptionCatchingRequestBody catchingBody = new ExceptionCatchingRequestBody(rawBody);
    	try {
      		T body = serviceMethod.toResponse(catchingBody);
      		return Response.success(body, rawResponse);
	    } catch (RuntimeException e) {
      		catchingBody.throwIfCaught();
      		throw e;
    	}
    }
}

调用ServiceMethod对象的toResponse解析,然后调用Response.success方法返回。

我们来看一下ServiceMethodtoResponse的方法。

final class ServiceMethod<R, T>  { 
    private final Converter<ResponseBody, R> responseConverter;
	R toResponse(ResponseBody body) throws IOException {
    	return responseConverter.convert(body);
  	}
}

最后是通过Converter转化body到相应的类。

至此我们的分析基本完成了。

总结:

  • 我们获取Retrofit对象时,是通过RetrofitBuilder的构建,当未设置其他参数时,Platoform类会提供默认的设置
  • 获取Call对象的时候设计到Java代理,然后通过ServiceMethod对象接口的注解进行解析保存
  • 调用Call的时候会创建okhttp3.Call对象来进行网络请求,最后通过Convert转化body相应的对象。

结构设计

上面流程基本完成了,下面我们来看一下Retrofit的结构设计。

Retrofit源码解析

  • Retrofit和Retrofit.Builder使用Facade模式封装底层的子系统,并且使用Builder模式来组织。
  • ServiceMethod主要是因此解析注解参数,协调各个类的工作,有点类似中介者模式。
  • ParameterHandler用于解析接口方法的参数
  • CallAdapter适配Call到对应的类,相关的类的使用设计模式非常多,后面我们再分析
  • Converter用于转化响应到对应的结构。

下面我们一一分析

Retrofit和Retrofit.Builder

Retrofit源码解析

RetrofitRetrofit.Builder采用了Builder设计模式,让Retrofit对象的创建与使用相分离。通过不同的创建的步骤不同,Retrofit也不同。

同时Retrofit.Builder依赖Platform类,Platform与平台相关的类,Platform类使用了单例和抽象工厂。

Platform中创建了一组平台相关的默认的CallAdapter.FactoryConverter.Factory和回调的Executor

Call相关的类设计

Retrofit源码解析

Call采用了装饰者模式,OkHttpCall实现了Call,而ExecutorCallbackCall则是装饰者,主要是增强的功能是回调的接口在相应的Executor中执行。Android中是主线程的Executor。

Retrofit源码解析

CallAdapter使用的是还有适配器模式和抽象工厂模式。

CallAdapter适配Call到对应的类。ExecutorCallAdapterFactoryCallAdapter的匿名内部类适配CallExecutorCallbackCallDefaultCallAdapterFactory中的CallAdapter匿名内部类会直接返回CallRxJava2CallAdapter会适配CallObservable

CallAdapter.Factory使用的是抽象工厂模式。用于创建CallAdapter

Converter相关的类设计

Retrofit源码解析

Converter用于转化响应到相关的类。Converter.FactoryConverter采用了抽象工厂模式。BuiltnConverter中也封装了其他的转化器。

相关文章:

  • 2021-09-18
  • 2021-05-03
  • 2021-06-10
  • 2022-01-04
  • 2022-12-23
  • 2021-10-26
  • 2022-01-01
  • 2022-12-23
猜你喜欢
  • 2022-01-19
  • 2021-04-02
  • 2022-12-23
  • 2022-12-23
  • 2021-12-28
相关资源
相似解决方案