阅读 1256

Retrofit源码分析

概述

Retrofit 是一个用于 Android 和 Java 平台的类型安全的网络请求框架。Retrofit 是一个 RESTful 的 HTTP 网络请求框架的封装。 网络请求的工作本质上是 OkHttp 完成,而 Retrofit 仅负责 网络请求接口的封装,可以结合Rxjava、协程、以及LiveData使用。返回的序列化数据可以是 Gson、Jackson、Moshi、Protobuf等等

源码使用

创建以及使用

同样是Builder的模式创建的,可以指定BaseUrl,指定OkHttpClient,指定适配器,以及序列号工厂

  1. 创建Retrofit
 Retrofit retrofit=new Retrofit.Builder()
                .baseUrl(baseUrl)
                .client(new OkHttpClient())
                // 指定Rxjava适配器
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                // 指定序列化结构
                .addConverterFactory(GsonConverterFactory.create())
                .build();

复制代码
  1. 创建接口
public interface ApiService {
    @GET("/wxarticle/list")
    Call<ResponseBody> getNetData();
    @GET("/wxarticle/list")
    Observable<ResponseBody> getNetData2();
}
复制代码
  1. 请求
 // 创建 ApiService
 ApiService apiService = retrofit.create(ApiService.class);
 // 使用原始自带的请求
  retrofit2.Call<NetData> netData = apiService.getNetData();
  netData.enqueue(new retrofit2.Callback<NetData>() {
      @Override
      public void onResponse(retrofit2.Call<NetData> call, retrofit2.Response<NetData> response) {

      }

      @Override
      public void onFailure(retrofit2.Call<NetData> call, Throwable t) {

      }
  });

 // 适配成Rxjava流的请求
  apiService.getNetData2()
          .subscribeOn(Schedulers.io())
          .observeOn(AndroidSchedulers.mainThread())
          .subscribe(data -> {
          }, error -> {
          });
复制代码

解析

创建retrofit的 Builder.Build方法

 public Retrofit build() {
    if (baseUrl == null) {
      throw new IllegalStateException("Base URL required.");
    }
	// 虽然这里用的工厂模式,但是 就new了一个OkHttpClient
    okhttp3.Call.Factory callFactory = this.callFactory;
    if (callFactory == null) {
      callFactory = new OkHttpClient();
    }

    Executor callbackExecutor = this.callbackExecutor;
    if (callbackExecutor == null) {
    // 因为在android中platform就是 Android,Platform中的一个内部类Android
      callbackExecutor = platform.defaultCallbackExecutor();
    }

    // 这就是添加所有的adapter,这里用到的适配器模式,也就是从Okhttp的Call适配成Retrofit的Call
    // 也可以添加咱们自己的适配器,比如RxJava2CallAdapterFactory.create(),Rxjava的。
    // 还可以添加协程的 或者是LiveData的
    
    List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
    callAdapterFactories.addAll(platform.defaultCallAdapterFactories(callbackExecutor));

    // 这个是转化成javabean的转化类,有Gson 有 Moshi,有Protobuf,
    List<Converter.Factory> converterFactories =
        new ArrayList<>(
            1 + this.converterFactories.size() + platform.defaultConverterFactoriesSize());

    converterFactories.add(new BuiltInConverters());
    converterFactories.addAll(this.converterFactories);
    converterFactories.addAll(platform.defaultConverterFactories());
 // 执行 Retrofit 的构造方法
    return new Retrofit(
        callFactory,
        baseUrl,
        unmodifiableList(converterFactories),
        unmodifiableList(callAdapterFactories),
        callbackExecutor,
        validateEagerly);
  }
  
 // 创建APIService,用的是动态代理的模式,在运行时创建了一个对象
public <T> T create(final Class<T> service) {
    validateServiceInterface(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 @Nullable Object invoke(Object proxy, Method method, @Nullable Object[] args)
                  throws Throwable {
                // 如果是来自Object方法,继续走原来的逻辑
                if (method.getDeclaringClass() == Object.class) {
                  return method.invoke(this, args);
                }
                args = args != null ? args : emptyArgs;
                 // 这个在Android中 isDefaultMethod()方法默认返回false。因为咱们就是用的接口中的方法
                 // 不会调用接口中的默认方法
                 //Java 8 引入了新的语言特性——默认方法(Default Methods
                 // 所以会走 loadServiceMethod(method).invoke(args)
                return platform.isDefaultMethod(method)
                    ? platform.invokeDefaultMethod(method, service, proxy, args)
                    : loadServiceMethod(method).invoke(args);
              }
            });
  }
  
  
  // 返回一个ServiceMethod,执行里面的方法
 ServiceMethod<?> loadServiceMethod(Method method) {
  // 先从缓存中拿,有直接返回
  ServiceMethod<?> result = serviceMethodCache.get(method);
  if (result != null) return result;
  synchronized (serviceMethodCache) {
    result = serviceMethodCache.get(method);
    if (result == null) {
     // 因为用的反射,所以缓存一份
     // 这里会返回 HttpServiceMethod ,ServiceMethod的一个子类
      result = ServiceMethod.parseAnnotations(this, method);
      serviceMethodCache.put(method, result);
    }
  }
  return result;
}
复制代码

HttpServiceMethod:把Retorfit的注解参数以及Url 变成 Okhttp的Requst,有返回回来的Respone,还有在这里适配的请求,以及 适配成各种返回值,默认 Okhttp的Call 适配成 Retrofit的Call,或者 Rxjava 的 Observable,或者是协程,以及序列化 都是在这里转化的

看一下 请求,直接看默认的,不用看Rxjava的即可,看Retrofit的Call怎样转化到Okhttp的Call的

当我们执行的时候会走到 HttpServiceMethod中的invoke

abstract class HttpServiceMethod<ResponseT, ReturnT> extends ServiceMethod<ReturnT> {
  static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations(
      Retrofit retrofit, Method method, RequestFactory requestFactory) {
      // 是否是kotlin中的协程方法
    boolean isKotlinSuspendFunction = requestFactory.isKotlinSuspendFunction;
    boolean continuationWantsResponse = false;
    boolean continuationBodyNullable = false;
	// 得到所有的注解
    Annotation[] annotations = method.getAnnotations();
    // 获取返回类型
    Type adapterType;
    // 先不看 有关协程的,
    if (isKotlinSuspendFunction) {
      Type[] parameterTypes = method.getGenericParameterTypes();
      Type responseType =
          Utils.getParameterLowerBound(
              0, (ParameterizedType) parameterTypes[parameterTypes.length - 1]);
      if (getRawType(responseType) == Response.class && responseType instanceof ParameterizedType) {
        // Unwrap the actual body type from Response<T>.
        responseType = Utils.getParameterUpperBound(0, (ParameterizedType) responseType);
        continuationWantsResponse = true;
      } else {
      }

      adapterType = new Utils.ParameterizedTypeImpl(null, Call.class, responseType);
      annotations = SkipCallbackExecutorImpl.ensurePresent(annotations);
    } else {
    // 获取返回类型
      adapterType = method.getGenericReturnType();
    }

 // 这里会走到Retrofit的nextCallAdapter方法,也就是从刚才咱们设置的Adapter的集合中遍历拿到 这个返回类型的
    CallAdapter<ResponseT, ReturnT> callAdapter =
        createCallAdapter(retrofit, method, adapterType, annotations);
      // 得到返回序列化类型,下面通过这个类型去找 序列化方法
    Type responseType = callAdapter.responseType();
    if (responseType == okhttp3.Response.class) {
         }
    if (responseType == Response.class) {
      throw methodError(method, "Response must include generic type (e.g., Response<String>)");
    }
    if (requestFactory.httpMethod.equals("HEAD") && !Void.class.equals(responseType)) {
      throw methodError(method, "HEAD method must use Void as response type.");
    }

 // 拿到 刚才设置的 converterFactories 集合,遍历拿到属于序列化方式
    Converter<ResponseBody, ResponseT> responseConverter =
        createResponseConverter(retrofit, method, responseType);

    okhttp3.Call.Factory callFactory = retrofit.callFactory;
    if (!isKotlinSuspendFunction) {
    // 咱们先看这个不是协程的,CallAdapted 就是ResponseCallAdapter 或者是 RxJava2CallAdapter
      return new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter);
    } 
  }

}

复制代码

刚才咱们也看到了OkHttpCall,这里面封装这Okhttp的Call。当我们调用请求的时候,实际就是调用的Okhttp的请求

final class OkHttpCall<T> implements Call<T> {
@Override
  public void enqueue(final Callback<T> callback) {
    Objects.requireNonNull(callback, "callback == null");
	// 拿到Okhttp的call
    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 {
         // 默认使用的就是OkhttpClient的 new Call,上面说过,虽然用的是工厂,但是还是直接new的OkHttpClient
          call = rawCall = createRawCall();
        } catch (Throwable t) {
          throwIfFatal(t);
          failure = creationFailure = t;
        }
      }
    }

// 调用请求
    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) {
              throwIfFatal(e);
              callFailure(e);
              return;
            }
          private void callFailure(Throwable e) {
            try {
              callback.onFailure(OkHttpCall.this, e);
            } catch (Throwable t) {
                          t.printStackTrace(); // TODO this is not great
            }
          }
        });
  }
}

// 解析返回值
Response<T> parseResponse(okhttp3.Response rawResponse) throws IOException {
 try {
   // responseConverter 就是默认的转化器,GsonRequestBodyConverter也可以,序列化成对应的格式
      T body = responseConverter.convert(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;
    }
}
复制代码
文章分类
后端
文章标签