Android Retrofit源码分析

作为我最爱的一个网络请求库,怎么不来搞搞它呢?

其实Retrofit是OKHTTP的一个封装,它的网络请求还是交给OKHTTP来做的。

我们一般情况下,会这样来做实例化Retrofit:

 Retrofit client = new Retrofit.Builder()
                .baseUrl("xxxxx")
                .addConverterFactory(GsonConverterFactory.create())
                .build();

这里使用的是建造者模式,什么是建造者模式呢?将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
具体可以参考:https://www.jianshu.com/p/be290ccea05a

然后我们来看看我们的Retrofit:
首先创建了一个Retrofit.Builder对象,该类是Retrofit的静态内部类:

 public static final class Builder {
    private final Platform platform;
    
    //网络请求器的工厂,用来产生网络请求其(Call)
    private @Nullable okhttp3.Call.Factory callFactory;
    
    //网络请求的url地址
    private HttpUrl baseUrl;

	//数据转换工厂
    private final List<Converter.Factory> converterFactories = new ArrayList<>();
    
    //网络请求适配器工厂
    private final List<CallAdapter.Factory> adapterFactories = new ArrayList<>();

	//回调方法执行器
    private @Nullable Executor callbackExecutor;
	
	//标志位,是否提前对业务接口中的注解进行验证转换的标志位
    private boolean validateEagerly;

    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() {
    	//Platform.get()返回一个Platform对象,指定运行平台
      this(Platform.get());
    }


    ... ...
 }

在方面的代码中,我们是首先会去找到Retrofit运行的平台:

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) {
    }
    try {
      Class.forName("java.util.Optional");
      return new Java8();
    } catch (ClassNotFoundException ignored) {
    }
    return new Platform();
  }

对于我们安卓来说,肯定是返回Android实例了。

然后让converterFactories添加了一个BuiltInConverters对象,它是一个内置的转换工厂,它禁止重写它的任何方法,但是这样可以保证当使用converters的正确行为。

Builder对象构建好了后,调用了baseUrl方法:

public Builder baseUrl(String baseUrl) {
		//检查baseUrl不为null
      checkNotNull(baseUrl, "baseUrl == null");
      //将它转换为一个HttpUrl对象
      //在这里会检查baseUrl的正确性
      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");
      //把URL参数分割成几个路径碎片
      List<String> pathSegments = baseUrl.pathSegments();
      //检测最后一个碎片以检查URL参数是不是以/结尾
      //不是就抛出异常。
      if (!"".equals(pathSegments.get(pathSegments.size() - 1))) {
        throw new IllegalArgumentException("baseUrl must end in /: " + baseUrl);
      }
      //给baseUrl赋值
      this.baseUrl = baseUrl;
      return this;
    }

添加完baseUrl后,我们就会添加数据转换工厂:addConverterFactory(GsonConverterFactory.create())

首先我们看一下GsonConverterFactory的创建:

 public static GsonConverterFactory create() {
    return create(new Gson());
  }
  
  @SuppressWarnings("ConstantConditions") // Guarding public API nullability.
  public static GsonConverterFactory create(Gson gson) {
    if (gson == null) throw new NullPointerException("gson == null");
    return new GsonConverterFactory(gson);
  }
 private GsonConverterFactory(Gson gson) {
    this.gson = gson;
  }

可以看到,它创建了一个Gson对象,将Gson对象封装起来了。

/** Add converter factory for serialization and deserialization of objects. */
    public Builder addConverterFactory(Converter.Factory factory) {
      converterFactories.add(checkNotNull(factory, "factory == null"));
      return this;
    }

上面就是给converterFactories添加了一个factory。

接下来,调用build方法,建造Retrofit对象:

public Retrofit build() {
	
	//必须要有baseUrl
      if (baseUrl == null) {
        throw new IllegalStateException("Base URL required.");
      }
      //网络请求执行器
	//如果没有callFactory,默认使用OKHttpClient
      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));

		//在Builder构造的时候,添加了一个BuildInConverters()
		//数据转换工厂集合
      // Make a defensive copy of the converters.
      List<Converter.Factory> converterFactories = new ArrayList<>(this.converterFactories);
		
		//创建Retrofit对象
      return new Retrofit(callFactory, baseUrl, converterFactories, adapterFactories,
          callbackExecutor, validateEagerly);
    }

接下来,我们来看看Retrofit的构造:

public final class Retrofit {
// 网络请求配置对象(对网络请求接口中方法注解进行解析后得到的对象)
  // 作用:存储网络请求相关的配置,如网络请求的方法、
  //数据转换器、网络请求适配器、网络请求工厂、基地址等
  private final Map<Method, ServiceMethod<?, ?>> serviceMethodCache = new ConcurrentHashMap<>();

  final okhttp3.Call.Factory callFactory;
  final HttpUrl baseUrl;
  final List<Converter.Factory> converterFactories;
  final List<CallAdapter.Factory> adapterFactories;
  final @Nullable Executor callbackExecutor;
  final boolean validateEagerly;

  Retrofit(okhttp3.Call.Factory callFactory, HttpUrl baseUrl,
      List<Converter.Factory> converterFactories, List<CallAdapter.Factory> adapterFactories,
      @Nullable Executor callbackExecutor, boolean validateEagerly) {
    this.callFactory = callFactory;
    this.baseUrl = baseUrl;
    //只可以读,不能写
    this.converterFactories = unmodifiableList(converterFactories); // Defensive copy at call site.
     //只可以读,不能写
    this.adapterFactories = unmodifiableList(adapterFactories); // Defensive copy at call site.
    this.callbackExecutor = callbackExecutor;
    this.validateEagerly = validateEagerly;
  }
... ...
}

可以看到,Retrofit中的成员变量和Builder中的差不多,在构造Retrofit对象的时候,进行赋值。

当我们构造好了Retrofit后,我们会像这样进行网络请求,以get请求为例:

public interface GetService {

    @GET("book/{id}")
    Call<String> getRequest(@Path("id") int id);

}

 GetService service = client.create(GetService.class);
        Call<String> call = service.getRequest(1);
        call.enqueue(new Callback<String>() {
            @Override
            public void onResponse(Call<String> call, Response<String> response) {
                
            }

            @Override
            public void onFailure(Call<String> call, Throwable t) {

            }
        });

首先我们调用create方法得到GetService 对象:
在这是, Retrofit是通过外观模式&代理模式,使用create方法创建网络请求接口实例:

public <T> T create(final Class<T> service) {
	//验证service是interface
    Utils.validateServiceInterface(service);
    if (validateEagerly) {
    //判断是否需要提前验证
    //默认为false
      eagerlyValidateMethods(service);
    }
    //创建网络请求接口的动态代理对象,即通过动态代理创建网络请求接口实例
    //该动态代理主要是为了拿到网络请求接口实例上的所有注解
    return (T) Proxy.newProxyInstance(
    			service.getClassLoader(), //动态生成接口实现类
     			new Class<?>[] { service }, //动态创建实例
        		new InvocationHandler() { //代理类的方法的调用会交给它的invoke方法
        		
          		private final Platform platform = Platform.get();

          @Override public Object invoke(Object proxy, Method method, @Nullable Object[] args)throws Throwable {

			 //proxy是代理类对象
          //method是调用的代理类的哪个方法
          //args是方法的餐忽
            // 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);
          }
        });
  }

在上面的代码中,我们可以看到的是,主要是调用了Proxy.newProxyInstance方法,在这里主要使用到了动态代理,什么是动态代理呢?代理类在程序运行时创建的代理方法被称为动态代理,也就是说,在这种情况下,代理类并不是在Java代码中定义的,而是在运行时根据我们在Java代码中的“指示”动态生成的。
关于动态代理,可以参考:https://juejin.im/post/5ad3e6b36fb9a028ba1fee6a

我们先看看Proxy.newProxyInstance方法中做了什么:

 public static Object newProxyInstance(ClassLoader loader,
                                          Class<?>[] interfaces,
                                          InvocationHandler h)
        throws IllegalArgumentException
    {
        Objects.requireNonNull(h);

        final Class<?>[] intfs = interfaces.clone();
         //查找或生成指定的代理类
        Class<?> cl = getProxyClass0(loader, intfs);
			//得到cl的构造器
            final Constructor<?> cons = cl.getConstructor(constructorParams);
            final InvocationHandler ih = h;
            //检查cl的访问权限
            if (!Modifier.isPublic(cl.getModifiers())) {
                // Android-changed: Removed AccessController.doPrivileged
                cons.setAccessible(true);
            }
            //返回它的实例
            return cons.newInstance(new Object[]{h});
        } catch (IllegalAccessException|InstantiationException e) {
            throw new InternalError(e.toString(), e);
        } catch (InvocationTargetException e) {
            Throwable t = e.getCause();
            if (t instanceof RuntimeException) {
                throw (RuntimeException) t;
            } else {
                throw new InternalError(t.toString(), t);
            }
        } catch (NoSuchMethodException e) {
            throw new InternalError(e.toString(), e);
        }
    }

在这里,通过Proxy工具,为委托类的接口自动生成一个代理对象,后续的方法调用都是这个代理对象进行发起的,最终会执行到InvocationHandler#invoke方法。

然后我们看看这里InvocationHandler#invoke方法的实现:

@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);
            }
            //关注1
            //读取网络请求接口里的方法,并根据前面的配置好的属性配置serviceMethod对象
            ServiceMethod<Object, Object> serviceMethod =
                (ServiceMethod<Object, Object>) loadServiceMethod(method);
            //关注2
            //根据配置好的serviceMethod对象创建OkHttpCall对象
            OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
			//关注点3
			//调用OkHttp,并根据oKHttpCall返回Call(不考虑RxJava)
            return serviceMethod.callAdapter.adapt(okHttpCall);
          }

我们先看关注点1:

 ServiceMethod<Object, Object> serviceMethod =
                (ServiceMethod<Object, Object>) loadServiceMethod(method);

我们先看看看ServiceMethod是什么:

Adapts an invocation of an interface method into an HTTP call
将接口方法的调用调整为一个HTTP call
也就是哦说,一个serviceMethod对象对应于网络请求接口里的一个方法


private final Map<Method, ServiceMethod<?, ?>> serviceMethodCache 
														= new ConcurrentHashMap<>();
ServiceMethod<?, ?> loadServiceMethod(Method method) {
//在创建ServiceMethod对象前,先看serviceMethodCach有没有缓存之前创建过的网络请求
    ServiceMethod<?, ?> result = serviceMethodCache.get(method);
    if (result != null) return result;
	//设置同步锁
    synchronized (serviceMethodCache) {
      result = serviceMethodCache.get(method);
      if (result == null) {
      //创建ServiceMethod实例
        result = new ServiceMethod.Builder<>(this, method).build();
        serviceMethodCache.put(method, result);
      }
    }
    return result;
  }

然后我们看看ServiceMethod的创建:
首先是new ServiceMethod.Builder<>(this, method)

 Builder(Retrofit retrofit, Method method) {
      this.retrofit = retrofit;
      this.method = method;
      //获取网络请求接口方法里的注释
      this.methodAnnotations = method.getAnnotations();
      //获取网络请求接口方法里的参数类型
      this.parameterTypes = method.getGenericParameterTypes();
      //获取网络请求接口方法里的注释内容
      this.parameterAnnotationsArray = method.getParameterAnnotations();
    }

然后调用build方法:

 public ServiceMethod build() {
 	//根据网络请求接口方法的返回值和注解类型,从Retrofit对象中获取对应的网络请求适配器
      callAdapter = createCallAdapter();
      //获得该网络适配器返回的数据类型
      //如Call<String>
      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();

	//解析网络请求接口方法中的注解
      for (Annotation annotation : methodAnnotations) {
        parseMethodAnnotation(annotation);
      }

      if (httpMethod == null) {
        throw methodError("HTTP method annotation is required (e.g., @GET, @POST, etc.).");
      }

      if (!hasBody) {
        if (isMultipart) {
          throw methodError(
              "Multipart can only be specified on HTTP methods with request body (e.g., @POST).");
        }
        if (isFormEncoded) {
          throw methodError("FormUrlEncoded can only be specified on HTTP methods with "
              + "request body (e.g., @POST).");
        }
      }
	//参数数量
      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);
      }

      if (relativeUrl == null && !gotUrl) {
        throw methodError("Missing either @%s URL or @Url parameter.", httpMethod);
      }
      if (!isFormEncoded && !isMultipart && !hasBody && gotBody) {
        throw methodError("Non-body HTTP method cannot contain @Body.");
      }
      if (isFormEncoded && !gotField) {
        throw methodError("Form-encoded method must contain at least one @Field.");
      }
      if (isMultipart && !gotPart) {
        throw methodError("Multipart method must contain at least one @Part.");
      }

      return new ServiceMethod<>(this);
    }

我们一个一个的看
先看如何得到的网络请求适配器:

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);
      }
    }
    
//retrofit.java
 public CallAdapter<?, ?> callAdapter(Type returnType, Annotation[] annotations) {
    return nextCallAdapter(null, returnType, annotations);
  }

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

    int start = adapterFactories.indexOf(skipPast) + 1;
    //遍历 CallAdapter.Factory 集合寻找合适的工厂(该工厂集合在第一步构造 Retrofit 对象时进行添加
    //在这里是默认的:ExecutorCallAdapterFactory
    for (int i = start, count = adapterFactories.size(); i < count; i++) {
      CallAdapter<?, ?> adapter = adapterFactories.get(i).get(returnType, annotations, this);
      if (adapter != null) {
        return adapter;
      }
    }
... ...
  }

接下来是获取数据转换器:

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

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


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;
    //循环遍历,得到数据转换器
    //在这里是 GsonResponseBodyConverter
    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;
      }
    }

接下来就是解析方法的注解:

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.");
        }
      } else if (annotation instanceof PATCH) {
        parseHttpMethodAndPath("PATCH", ((PATCH) annotation).value(), true);
      } else if (annotation instanceof POST) {
        parseHttpMethodAndPath("POST", ((POST) annotation).value(), true);
      } else if (annotation instanceof PUT) {
        parseHttpMethodAndPath("PUT", ((PUT) annotation).value(), true);
      } else if (annotation instanceof OPTIONS) {
        parseHttpMethodAndPath("OPTIONS", ((OPTIONS) annotation).value(), false);
      } else if (annotation instanceof HTTP) {
        HTTP http = (HTTP) annotation;
        parseHttpMethodAndPath(http.method(), http.path(), http.hasBody());
      } else if (annotation instanceof retrofit2.http.Headers) {
        String[] headersToParse = ((retrofit2.http.Headers) annotation).value();
        if (headersToParse.length == 0) {
          throw methodError("@Headers annotation is empty.");
        }
        //添加header
        headers = parseHeaders(headersToParse);
      } else if (annotation instanceof Multipart) {
        if (isFormEncoded) {
          throw methodError("Only one encoding annotation is allowed.");
        }
        isMultipart = true;
      } else if (annotation instanceof FormUrlEncoded) {
        if (isMultipart) {
          throw methodError("Only one encoding annotation is allowed.");
        }
        isFormEncoded = true;
      }
    }

在这些步骤做完后,就构建一个ServiceMethod:

ServiceMethod(Builder<R, T> builder) {
    this.callFactory = builder.retrofit.callFactory();
    this.callAdapter = builder.callAdapter;
    this.baseUrl = builder.retrofit.baseUrl();
    this.responseConverter = builder.responseConverter;
    this.httpMethod = builder.httpMethod;
    this.relativeUrl = builder.relativeUrl;
    this.headers = builder.headers;
    this.contentType = builder.contentType;
    this.hasBody = builder.hasBody;
    this.isFormEncoded = builder.isFormEncoded;
    this.isMultipart = builder.isMultipart;
    this.parameterHandlers = builder.parameterHandlers;
  }

我们可以总结一下,是如何得到ServiceMethod的:

  1. 先从serviceMethodCache根据method,查询是否存在关于这个method的ServiceMethod
  2. 如果存在,就直接返回
  3. 如果不存在,就调用new ServiceMethod.Builder<>(this, method).build();创建ServiceMethod
    1. 先得到网络适配器callAadpter,如果进行设置,就是默认的,并得到responseType。
    2. 得到数据转换器responseConverter,一般我们会使用GsonConverterFactory,它会调用responseBodyConverter方法,得到Gson的数据转换器:GsonResponseBodyConverter
    3. 然后遍历循环方法的注解,解析方法的注解,得到httpMethodhasBodyrelativeUrlrelativeUrlParamNamesheaders
    4. 接下来遍历循环方法的参数,为每一个方法的参数创建一个ParameterHandler<?>对象并解析每个参数使用的注解类型
    5. 创建ServiceMethod,返回
  4. 将返回来的ServiceMethod保存到serviceMethodCache

接下来,回到invoke方法,我们看关注2:

  OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);

在这里创建了一个OkHttpCall实例,OkHttpCall实现了Call<T>:

final class OkHttpCall<T> implements Call<T> {
  private final ServiceMethod<T, ?> serviceMethod;//包含了所有网络请求参数信息
  private final @Nullable Object[] args; //接口参数

  private volatile boolean canceled;

  @GuardedBy("this")
  private @Nullable okhttp3.Call rawCall;
  @GuardedBy("this")
  private @Nullable Throwable creationFailure; // Either a RuntimeException or IOException.
  @GuardedBy("this")
  private boolean executed;

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

创建好了OkHttpCall之后,我们看关注点3:

return serviceMethod.callAdapter.adapt(okHttpCall);

在这里,我们没有设置网络请求适配器,那么就会使用Retrofit默认的: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) {
    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);
      }
    };
  }

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

这里采用了装饰模式,ExecutorCallbackCall = 装饰者,而里面真正去执行网络请求的还是OkHttpCall
使用装饰模式的原因:希望在OkHttpCall发送请求时做一些额外操作。这里的额外操作是线程转换,即将子线程切换到主线程

在接口的代理实例创建好了后,我们会调用它的方法得到一个Call实例:

Call<String> call = service.getRequest(1);

我们知道,service对象实例上是动态代理对象Proxy.newProxyInstance(),并不是真正的网络请求接口创建的对象。
当这个代理对象调用getRequest方法的时候,会被这个拦截,调用自身的InvocationHandler # invoke()
然后就会创建一个Call对象返回。

进行网络请求
call.enqueue(new Callback<String>() {
            @Override
            public void onResponse(Call<String> call, Response<String> response) {

            }

            @Override
            public void onFailure(Call<String> call, Throwable t) {

            }
        });

我们知道,在这里call是ExecutorCallAdapterFactory的实例:

 @Override public void enqueue(final Callback<T> callback) {
      checkNotNull(callback, "callback == null");
	
	//delegate是OkHttpCall的实例
      delegate.enqueue(new Callback<T>() {
        @Override public void onResponse(Call<T> call, final Response<T> response) {
        //线程切换,主要是通过Handler
          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);
            }
          });
        }
      });
    }

我们看看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 {
        //创建OkHttp的Request对象,在封装成OkHttp.call
          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();
        }
      }
    });
  }

我们先看看它是怎么创建okhttp3.Call call:

private okhttp3.Call createRawCall() throws IOException {
    Request request = serviceMethod.toRequest(args);
    okhttp3.Call call = serviceMethod.callFactory.newCall(request);
    if (call == null) {
      throw new NullPointerException("Call.Factory returned null.");
    }
    return call;
  }

@Override public Call newCall(Request request) {
    return new RealCall(this, request, false /* for web socket */);
  }

我们可以看到,它创建了OkHttp的RealCall对象,然后进行网络请求,之后的操作就交给了OkHttp,
如果请求成功,就会到okhttp3.Callback()onResponse方法,在该方法中,解析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 {
      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;
    }
  }

可以看到,主要调用了serviceMethod.toResponse(catchingBody),进行body解析,在这个方法中,会调用GsonResponseBodyConverter.convert方法,进行json数据解析。

接下来,会调用callSuccess方法:

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

这个callback是在调用delegate.enqueue方法时,传入的参数,之后到这个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() {
              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);
            }
          });
        }
      });

然后会调用callbackExecutor.execute(Runnable)方法,callbackExecutor是在Retrofit实例在创建的时候,被初始化的:

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

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

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

}

可以看到,之后的操作就交给了Handler,该Handler是主线程的Handler,因此就实现线程切换。

参考:https://www.jianshu.com/p/0c055ad46b6c

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值