Retrofit源码解析

一、Retrofit创建过程源码解析
 mRetrofit = new Retrofit.Builder()
             .baseUrl(HttpConfig.BASE_URL) // 设置网络请求的Url地址
             .client(mOkHttpClient)
             .addConverterFactory(GsonConverterFactory.create()) // 设置数据解析器
             .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) // 支持RxJava平台
             .build();

Retrofit是通过Builder构建者模式创建的,先看下创建Builder时Builder的构造方法:

public Builder() {
    this(Platform.get());
}

Platform的get()方法:

 private static final Platform PLATFORM = findPlatform();

  static Platform get() {
    return PLATFORM;
  }

最终调用的是Platform类中的findPlatform方法,findPlatform方法源码,根据不同的平台提供对应平台的线程池:

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

Builder的client方法设置OkHttpClient对象:

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

Builder的build方法:

 public Retrofit build() {

	  //注释1
      if (baseUrl == null) {
        throw new IllegalStateException("Base URL required.");
      }

	  //注释2
      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> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
      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);

	  //创建Retrofit对象
      return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories),
          unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);
    }

由注释1处可知,baseUrl不能为空,否则会抛异常,在注释2处会判断Builder的client方法中有没有设置OkHttpClient对象,如果没有设置就直接创建一个。

二、Retrofit的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, @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);
            }

			//注释3
            ServiceMethod<Object, Object> serviceMethod =
                (ServiceMethod<Object, Object>) loadServiceMethod(method);

			//注释4
            OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
            
            //注释5
            return serviceMethod.adapt(okHttpCall);
          }
        });
  }

注释3处会获取到ServiceMethod对象(如果有缓存直接拿缓存对象,如果没有缓存,就通过构建者模式创建ServiceMethod对象),ServiceMethod是对用户自定义请求方法的信息封装,它里面包含方法名称、注解、注解值等所有的方法信息,在创建ServiceMethod对象的时候,还会创建CallAdapter对象和Converter对象,CallAdapter是进行数据类型转换的(比如转换成Rxjava的Observable对象、LiveData对象等),Converter是对数据进行解析处理的(比如gson解析)。下面看下这两个对象的具体创建过程:

  • CallAdapter创建:在ServiceMethod.Builder的build方法中会调用createCallAdapter(),接着会调用retrofit的callAdapter方法,紧接着调用nextCallAdapter方法,在nextCallAdapter方法中会循环遍历callAdapterFactories列表,取出列表中的CallAdapter.Factory元素并通过其get方法获取对应的CallAdapter对象,如果获取到的CallAdapter对象不为空,则返回该对象
  • Converter创建:在ServiceMethod.Builder的build方法中会调用createResponseConverter()方法,接着调用retrofit的responseBodyConverter方法,然后调用nextResponseBodyConverter方法,在这个方法中会循环遍历converterFactories列表,取出列表中的Converter.Factory元素并通过其responseBodyConverter方法获取对应的Converter对象,如果取出的对象不为空,则返回该对象

上述CallAdapter.Factory的对象和Converter.Factory对象是在构建retrofit对象时通过builder的addConverterFactory方法和addCallAdapterFactory方法传递进去的,支持用户自定义

注释4处创建一个OkHttpCall对象,并将serviceMethod和参数值args传递进去,然后将这个对象作为了注释5处adapt的参数(其实下面的网络请求就是由该OkHttpCall进行的),OkHttpCall通过enqueue方法发起异步请求,在这个方法里会将真正的请求操作交给okhttp3.Call对象,如果okhttp3.Call对象为空,会调用createRawCall()方法去创建,在createRawCall()方法方法中又调用了serviceMethod.toCall(args)方法,然后又调用callFactory.newCall方法,这个callFactory是一个接口其类型是okhttp3.Call.Factory,它的实现类是OkHttpClient(从注释2处也可以看出,真正的实例对象是OkHttpClient对象),那么就继续查看下OkHttpClient的newCall方法:

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

从上面的方法中可以看出,最终是调用了RealCall的newRealCall方法创建了一个RealCall对象,而okhttp中就是通过这个对象发起网络请求的,所以retrofit就拥有了网络请求的能力

注释5处调用serviceMethod的adapt方法,这个方法中又调用了callAdapter的adapt方法,这个callAdapter对象就是注释3处创建的CallAdapter创建的对象RxJava2CallAdapter实例,接着在看下RxJava2CallAdapter的adapter方法:

  @Override public Object adapt(Call<R> call) {

	//注释6
    Observable<Response<R>> responseObservable = isAsync
        ? new CallEnqueueObservable<>(call)
        : new CallExecuteObservable<>(call);

	//注释7
    Observable<?> observable;
    if (isResult) {
      observable = new ResultObservable<>(responseObservable);
    } else if (isBody) {
      observable = new BodyObservable<>(responseObservable);
    } else {
      observable = responseObservable;
    }

    if (scheduler != null) {
      observable = observable.subscribeOn(scheduler);
    }

    if (isFlowable) {
      return observable.toFlowable(BackpressureStrategy.LATEST);
    }
    if (isSingle) {
      return observable.singleOrError();
    }
    if (isMaybe) {
      return observable.singleElement();
    }
    if (isCompletable) {
      return observable.ignoreElements();
    }
    return observable;
  }

可以看出这个adapter返回的是一个observable对象,从注释7处可知observable对象就是responseObservable或者是对responseObservable的一个包装,注释6处可以知道responseObservable是CallEnqueueObservable实例(只考虑异步请求),下面查看下相关源码,CallEnqueueObservable的subscribeActual方法:

 @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();
    CallCallback<T> callback = new CallCallback<>(call, observer);
    observer.onSubscribe(callback);

	//注释8
    call.enqueue(callback);
  }

从这个方法中可知,当responseObservable发生订阅的时候会调用subscribeActual方法,然后通过注释4处创建的Call对象发起异步网络请求,在callback回调中通过observer向下游发送对应的响应信息或者错误信息(该过程自行查看源码),这样下游(自己的业务层)就可以收到对应的网络请求结果了

在注释8处的call对象是OkHttpClient对象,查看下OkHttpClient的enqueue方法:

@Override public void enqueue(final Callback<T> callback) {
 
..........

okhttp3.Call call;

 call.enqueue(new okhttp3.Callback() {
      @Override public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse) {
        Response<T> response;
        try {

		  //注释9
          response = parseResponse(rawResponse);
        } catch (Throwable e) {
          callFailure(e);
          return;
        }

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

从方法中可以知道,发起网络请求是通过okhttp的call发起的,在okhttp3.Callback的回调中又调用了callback的onResponse回调(注释10处),这个callback是注释8处传递进来的回调对象。在注释9处对okhttp请求回来的原始数据rawResponse进行解析,在parseResponse方法中会取出原始数据rawResponse的body(业务数据),然后通过serviceMethod.toResponse对body进行解析,在serviceMethod.toResponse中是调用了responseConverter.convert(body)方法对数据进行解析(responseConverter对象就是上文中创建的Converter对象,convert里面的解析规则可以由用户自定义,主要是将json数据解析成最终返回的java对象)。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值