Retrofit 适配器源码详解

  • 前言

    Retrofit适配器,通俗的理解就是我们写的Service接口中的返回值类型适配,常用的类型有Call,Observable。

  • Retrofit的准备工作

    理解适配器前,我们先来了解一下retrofit的前期准备工作。


retrofit = new Retrofit.Builder()
               .client(client)//okhttpclient
               .validateEagerly(false)//是否需要进行懒加载
               //添加Rxjava适配器
               .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
               //添加Gson转换器,将字符流转换成javaBean
               .addConverterFactory(GsonConverterFactory.create())
               .baseUrl("https://xxx.com")
               .build();

分析之前先梳理一下retrofit的创建过程。这边的代码很简单,我就不进行过多叙述了。

  • Retrofit变量解释
//用于存储service方法中的注解值,和返回值等信息(一个method对应一个ServiceMethod)
 private final Map<Method, ServiceMethod<?, ?>> serviceMethodCache = new ConcurrentHashMap<>();

 final okhttp3.Call.Factory callFactory;//传入的okhttpclient
 final HttpUrl baseUrl;
 final List<Converter.Factory> converterFactories;
 final List<CallAdapter.Factory> callAdapterFactories;
 final @Nullable Executor callbackExecutor;//回调的线程池默认主线程
 final boolean validateEagerly;//是否懒加载
 
  • Retrofit.Build::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) {
           		//获取对应的平台 1
               callbackExecutor = platform.defaultCallbackExecutor();
           }

           // Make a defensive copy of the adapters and add the default Call adapter.
           List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
           //往callAdapter中加入默认适配器工厂
           callAdapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));

           // Make a defensive copy of the converters.
           List<Converter.Factory> converterFactories =
                   new ArrayList<>(1 + this.converterFactories.size());

           // 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());
           converterFactories.addAll(this.converterFactories);

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

这里没有什么好解释的,只是对Retrofit的一些初始化工作。其中 //1 处获取了回调的线程,首先platform会调用 Platform.get() 来获取。get 会返回PLATFORM静态变量,静态变量调用findPlatform()来进行初始化。我们看一下具体实现。


  private static Platform findPlatform() {
           try {
               Class.forName("android.os.Build");
               if (Build.VERSION.SDK_INT != 0) {
                   return new Platform.Android();
               }
           } catch (ClassNotFoundException ignored) {
           }
           try {
               Class.forName("java.util.Optional");
               return new Platform.Java8();
           } catch (ClassNotFoundException ignored) {
           }
           return new Platform();
       }
       

方法首先会进行类加载,尝试寻找是否存在 android.os.Build 类,如果存在就会创建Platform.Android()对象。很显然这就是我们要找的对象。


   static class Android extends Platform {
          @Override public Executor defaultCallbackExecutor() {
              return new Platform.Android.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(),它将任务都交给handler来进行执行,因此我们的默认回调线程是主线程。前面的callbackExecutor 就是这里的MainThreadExecutor ()。
defaultCallAdapterFactory()创建了ExecutorCallAdapterFactory()工厂,从这里咱知道默认的适配器工厂为ExecutorCallAdapterFactory(就是返回值为Call的工厂)


扯得有点远,咱们回归正题。继续上示例代码


  TestService service = retrofit.create(TestService.class);
       service.getData()
               .subscribeOn(Schedulers.io())
               .observeOn(AndroidSchedulers.mainThread())
               .subscribe(new Observer<ResponseBody>() {
                   @Override
                   public void onSubscribe(Disposable d) {

                   }

                   @Override
                   public void onNext(ResponseBody user) {
                       try {
                           Log.i(TAG, "onNext: " + user.string());
                       } catch (IOException e) {
                           e.printStackTrace();
                       }
                   }

                   @Override
                   public void onError(Throwable e) {
                       Log.i(TAG, "onError: " + e.getMessage());
                   }

                   @Override
                   public void onComplete() {

                   }
               });
               

这段代码我想大家不会陌生。创建完retrofit后,会调用retrofit::create(Service.class)来进行创建Service。我们来看看Service的创建过程。


  public <T> T create(final Class<T> service) {
     Utils.validateServiceInterface(service);
     if (validateEagerly) {//这里就是之前设置的参数,是否懒加载(默认是懒加载)
         eagerlyValidateMethods(service);//1
     }
     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)) {//默认false,咱不管
                         return platform.invokeDefaultMethod(method, service, proxy, args);
                     }
                     //为当前method加载一个ServiceMethod出来
                     ServiceMethod<Object, Object> serviceMethod =
                             (ServiceMethod<Object, Object>) loadServiceMethod(method);//2
                             //创建Okhttpcall之后的网络请求会用到
                     OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
                     //根据serviceMethod对okhttpcall进行适配
                     return serviceMethod.adapt(okHttpCall);//3
                 }
             });
 }
        

这里代码很简单,利用动态代理的形式对Service进行创建。不管如何网络请求都绕不开OkhttpCall对象。话不多说,先进性1处的分析。


 private void eagerlyValidateMethods(Class<?> service) {
      Platform platform = Platform.get();
      //加载Service中所有的method
      for (Method method : service.getDeclaredMethods()) {
          if (!platform.isDefaultMethod(method)) {//platform.isDefaultMethod(method)默认为false
              loadServiceMethod(method);
          }
      }
  }
    //存储method的信息,进入map中
 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();//4
               serviceMethodCache.put(method, result);
           }
       }
       return result;
   }

使用了双重检查锁,通过method在缓存中找,如果找不到则进行创建,并且加入缓存中。我们发现这里的loadServiceMethod()在 //2 处也有调用。因为此处是以缓存的方式进行存储,因此我们可以确定,之前的validateEagerly参数是懒加载的作用。
//4处代码暂且放一下,我们先进行 //3处的分析。


//serviceMethod.adapt(okHttpCall);
  T adapt(Call<R> call) {
    return callAdapter.adapt(call);
  }
  

代码简单的让人摸不着头脑,在这里我们要知道这个T是我们方法的Call或者Observable的泛型。要想知道适配器的实现,我们必须要知道callAdapter为何物。

接下来我们看4处的代码 ServiceMethod 的创建


   public ServiceMethod build() {
         callAdapter = createCallAdapter();//创建CallAdapter
         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);//解析方法上的注解
         }

       ...
         return new ServiceMethod<>(this);
     }
        
    private CallAdapter<T, R> createCallAdapter() {
    	//获取method的返回值Type(需要注意,后面会用到)
    	 Type returnType = method.getGenericReturnType();
    	...
            //这里通过最终在这里进行创建
          return (CallAdapter<T, R>) retrofit.callAdapter(returnType, annotations);
 		...
     }
     

代码有点长,我截取重要的来进行分析。这里我们找到了callAdapter赋值的地方。retrofit::callAdapter()接着会调用retrofit::nextCallAdapter()方法,这里有一个skipPast参数,为null传递进来,需要注意一下。我们接着看一看nextCallAdapter()的实现


  public CallAdapter<?, ?> nextCallAdapter(@Nullable CallAdapter.Factory skipPast, Type returnType,
      Annotation[] annotations) {
    checkNotNull(returnType, "returnType == null");
    checkNotNull(annotations, "annotations == null");
	//因为skipPast为null 所以这一步的执行结果应该为 start = -1+1 = 0
    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;
      }
    }

	...
  }

callAdapterFactories看到这里可能大家就熟悉了,这不是我们调用的时候创建的工厂吗。我们创建的工厂实例会被丢入到这个集合里,那我们get的时候恰好就是拿到我们创建的工厂 。
这里我需要提一嘴的是当前的callAdapter是ServiceMethod的成员变量,而ServiceMethod和method进行绑定,所以一个method应该对应一个callAdapter才合理。因此这里 我们大胆猜测 callAdapter会根据method的returnType不同来返回不同的CallAdapterFactory。(如果创建的时候加入了RxJava2CallAdapterFactory,那么这里的callAdapterFactories就应该会两个值,一个是RxJava2CallAdapterFactory和ExecutorCallAdapterFactory)。
我们主要分析RxJava2CallAdapterFactory代码,ExecutorCallAdapterFactory较为简单,大家有兴趣的自行去看。下面会执行RxJava2CallAdapterFactory::get()方法


    public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
        Class<?> rawType = getRawType(returnType);
        ...

        boolean isFlowable = rawType == Flowable.class;
        boolean isSingle = rawType == Single.class;
        boolean isMaybe = rawType == Maybe.class;
        //这里进行判断当前是否属于Rxjava适配器,不是返回null
        if (rawType != Observable.class && !isFlowable && !isSingle && !isMaybe) {
            return null;
        }

        boolean isResult = false;
        boolean isBody = false;
        Type responseType;
        if (!(returnType instanceof ParameterizedType)) {
            String name = isFlowable ? "Flowable"
                    : isSingle ? "Single"
                    : isMaybe ? "Maybe" : "Observable";
            throw new IllegalStateException(name + " return type must be parameterized"
                    + " as " + name + "<Foo> or " + name + "<? extends Foo>");
        }
		//获取returnType中的泛型Type
        Type observableType = getParameterUpperBound(0, (ParameterizedType) returnType);
        Class<?> rawObservableType = getRawType(observableType);
        if (rawObservableType == Response.class) {
            if (!(observableType instanceof ParameterizedType)) {
                throw new IllegalStateException("Response must be parameterized"
                        + " as Response<Foo> or Response<? extends Foo>");
            }
            responseType = getParameterUpperBound(0, (ParameterizedType) observableType);
        } else if (rawObservableType == Result.class) {
            if (!(observableType instanceof ParameterizedType)) {
                throw new IllegalStateException("Result must be parameterized"
                        + " as Result<Foo> or Result<? extends Foo>");
            }
            responseType = getParameterUpperBound(0, (ParameterizedType) observableType);
            isResult = true;
        } else {
        	//我们会执行到这里
            responseType = observableType;
            isBody = true;	//这个关系到我们接下来创建的对象
        }
		//这里就是我们需要找到CallAdapter的实现类的
        return new RxJava2CallAdapter(responseType, scheduler, isAsync, isResult, isBody, isFlowable,
                isSingle, isMaybe, false);
    }
    

我们先收一收思绪,前面我们讲的Retrofit::create()方法中动态代理返回的是callAdapter.adapter的对象。所以我们接下来看RxJava2CallAdapter的adapter方法,看它是如何进行适配的。


  @Override public Object adapt(Call<R> call) {
  	//这里对Observable进行创建
    Observable<Response<R>> responseObservable = isAsync
        ? new CallEnqueueObservable<>(call)
        : new CallExecuteObservable<>(call);

    Observable<?> observable;
    if (isResult) {
      observable = new ResultObservable<>(responseObservable);
    } else if (isBody) {
    //通过上面得知 isBody为true因此,会执行到这里,这个类主要是对响应结果进行包装,暂时先不管
      observable = new BodyObservable<>(responseObservable);
    } else {
      observable = responseObservable;
    }

 	...
 	
    return observable;
  }
  

下面咱看一看CallExecuteObservable类的实现


final class CallExecuteObservable<T> extends Observable<Response<T>> {
  private final Call<T> originalCall;

  CallExecuteObservable(Call<T> originalCall) {
    this.originalCall = originalCall;
  }
//Observable执行subscribe时最终会调用这个方法(想了解更多的小伙伴可以看一下rxjava源码,了解一下架构方式)
  @Override protected void subscribeActual(Observer<? super Response<T>> observer) {
    // Since Call is a one-shot type, clone it for each new observer.
    Call<T> call = originalCall.clone();//这个call就是前面传进来的okhttpCall
    CallDisposable disposable = new CallDisposable(call);
    observer.onSubscribe(disposable);

    boolean terminated = false;
    try {
    //最后都会执行这一步进行网络请求
      Response<T> response = call.execute();
      if (!disposable.isDisposed()) {
        observer.onNext(response);
      }
      if (!disposable.isDisposed()) {
        terminated = true;
        observer.onComplete();
      }
    } catch (Throwable t) {
      Exceptions.throwIfFatal(t);
      if (terminated) {
        RxJavaPlugins.onError(t);
      } else if (!disposable.isDisposed()) {
        try {
          observer.onError(t);
        } catch (Throwable inner) {
          Exceptions.throwIfFatal(inner);
          RxJavaPlugins.onError(new CompositeException(t, inner));
        }
      }
    }
  }

}

到了这里我们进行一个总结,Retrofit::create方法中使用动态代理对每一个method进行拦截,并根据返回值的Type 来返回不同的adapter,我们使用Rxjava就是RxJava2CallAdapter这个适配器。在这个类中对Observable进行创建,并且在subscribe的时候调用OkhttpCall的execute()方法,来进行网络请求。并返回我们需要的结果Response。Rxjava会根据Response的结果来进行返回。到了这里我们应该对Retrofit的适配器模式有了大概的了解,现在唯一模糊的就是Response是怎么创建来的?


下面我们继续看OkhttpCall的execute()方法


  @Override public Response<T> execute() throws IOException {
    okhttp3.Call call;

    synchronized (this) {
      if (executed) throw new IllegalStateException("Already executed.");
      executed = true;

      if (creationFailure != null) {
        if (creationFailure instanceof IOException) {
          throw (IOException) creationFailure;
        } else if (creationFailure instanceof RuntimeException) {
          throw (RuntimeException) creationFailure;
        } else {
          throw (Error) creationFailure;
        }
      }

      call = rawCall;
      if (call == null) {
        try {
          call = rawCall = createRawCall();//这里会进行跟Okhttp联系起来,创建RawCall
        } catch (IOException | RuntimeException | Error e) {
          throwIfFatal(e); //  Do not assign a fatal error to creationFailure.
          creationFailure = e;
          throw e;
        }
      }
    }

    if (canceled) {
      call.cancel();
    }

    return parseResponse(call.execute());//call.execute()拿到rawCall,并执行execute()
  }
  

继续看createRawCall()方法

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

向下跟 toCall()


okhttp3.Call toCall(@Nullable Object... args) throws IOException {
    RequestBuilder requestBuilder = new RequestBuilder(httpMethod, baseUrl, relativeUrl, headers,
        contentType, hasBody, isFormEncoded, isMultipart);

    @SuppressWarnings("unchecked") // It is an error to invoke a method with the wrong arg types.
    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());
  }
  

最后会执行callFactory.newCall()方法。这个callFactory就是创建Retrofit时候的 client(),有映像的同学应该会发现,newCall会调用OkhttpClient的newCall()。这里就属于Okhttp的范畴了,我就不向下分析。我们继续回到上面call.execute()会返回一个response,这个response就是网络请求返回的结果。Okhttp采用的是Socket通信,网络请求后会进行阻塞等待返回结果,(我们可以将其看成是一个线程的同步执行)如果请求成功Response必然是存在值的。下面我们来看OkhttpCall的parseResponse方法。


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);//这里会根据我们设置Gson转换器,将body转换成javabean
      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;
    }
  }
  

执行成功会调用 Response.success(body, rawResponse)


public static <T> Response<T> success(@Nullable T body, okhttp3.Response rawResponse) {
    checkNotNull(rawResponse, "rawResponse == null");
    if (!rawResponse.isSuccessful()) {
      throw new IllegalArgumentException("rawResponse must be successful response");
    }
    return new Response<>(rawResponse, body, null);
  }
  

然后根据body创建Response返回。


Retrofit的适配器就分析到这里。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值