0
点赞
收藏
分享

微信扫一扫

Retrofit2源码解析

Retrofit是一个RESTful的http网络请求的封装。网络请求本质上是有Okhttp完成,而Retrofit仅负责网络请求接口的封装。

  • App应用程序通过Retrofit请求网络,实际上是使用Retrofit接口层封装请求参数、Header、Url等信息,之后有Okhttp完成后续的请求操作。
  • 在服务端返回数据后,Okhttp将原始的结果交给Retrofit,Retrofit根据用户的需求对结果进行解析。
请求过程伪代码:
        val retrofit = Retrofit.Builder()
                .baseUrl(SERVER_ADDRESS)
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .addConverterFactory(GsonConverterFactory.create())
                .client(mOkHttpClient)
                .build()
        var service = retrofit.create(MyService.class)
        service.getData()
创建Retrofit流程图

1、构建一个Retrofit实例;
2、创建网络请求接口IService和请求属性注解;
3、通过动态代理解析请求接口的注解,并生成网络请求Call对象;
4、通过CallAdapter将Retrofit的Call转化为Okhttp的Call;
5、通过OkHttpCall发送网络请求;
6、通过Converter数据转换适配器转换请求返回的数据;
7、通过线程切换执行器切换到主线程。
Retrofit优势:

1.采用大量注解,对网络请求参数进行适配,以满足RESTful风格,注解包括:


2.将Okhttp进行封装

3.对请求结果进行封装

源码分析

Retrofit部分代码:

public final class Retrofit {
  //网络请求缓存,如:请求方法、请求头、请求体,各种适配器等
  private final Map<Method, MethodHandler> methodHandlerCache = new LinkedHashMap<>();
  //okhttp工厂,真正发送交易的处理类
  private final okhttp3.Call.Factory callFactory;
  //请求url域名
  private final BaseUrl baseUrl;
  //数据转换器工厂集
  private final List<Converter.Factory> converterFactories;
  //网络请求适配器工厂集
  private final List<CallAdapter.Factory> adapterFactories;
  //异步请求结果线程切换执行器
  private final Executor callbackExecutor;
  //标志位、是否马上解析接口方法
  private final boolean validateEagerly;

  Retrofit(okhttp3.Call.Factory callFactory, BaseUrl baseUrl,
      List<Converter.Factory> converterFactories, List<CallAdapter.Factory> adapterFactories,
      Executor callbackExecutor, boolean validateEagerly) {
    this.callFactory = callFactory;
    this.baseUrl = baseUrl;
    this.converterFactories = converterFactories;
    this.adapterFactories = adapterFactories;
    this.callbackExecutor = callbackExecutor;
    this.validateEagerly = validateEagerly;
  }
}

converterFactory
数据解析Converter,将response通过converterFactory转换成对应的数据形式,GsonConverterFactory,FastJsonConverterFactory。

callAdapterFactory
经过converter转换的数据形势,通过calladapter转换成其他数据方式。如rxjavaCallFactory对应的Observable。

ServiceMethod
核心处理类,解析方法和注解,toRequest()方法中生成HttpRequest。创建responseConverter(将response流转换为String或实体),创建callAdapter

Retrofit内部类Builder代码:
Retrofit通过建造者模式进行创建并设置属性,所以Builder类中与Retrofit类属性相同。使用建造者模式的条件为有4-5个构造函数的参数,且有可选参数组合,Retrofit满足该条件,所以使用了建造者模式。

  public static final class Builder {
    private okhttp3.Call.Factory callFactory;
    private BaseUrl baseUrl;
    private List<Converter.Factory> converterFactories = new ArrayList<>();
    private List<CallAdapter.Factory> adapterFactories = new ArrayList<>();
    private Executor callbackExecutor;
    private boolean validateEagerly;
}

调用build方法:

    public Retrofit build() {
      if (baseUrl == null) {
        throw new IllegalStateException("Base URL required.");
      }
      //默认使用okhttp请求
      okhttp3.Call.Factory callFactory = this.callFactory;
      if (callFactory == null) {
        callFactory = new OkHttpClient();
      }

    //添加一下线程切换管理器,okhttp切换线程需要手动,retrofit能自动切换,内部使用的是handler进行线程切换。
      Executor callbackExecutor = this.callbackExecutor;
      if (callbackExecutor == null) {
        callbackExecutor = platform.defaultCallbackExecutor();
      }

      //添加我们传入的callAdapter
      List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories); 
  //添加一个默认的callAdpater,将okhttp的call转为retrofit的call      callAdapterFactories.addAll(platform.defaultCallAdapterFactories(callbackExecutor));
      
      List<Converter.Factory> converterFactories =
          new ArrayList<>(
              1 + this.converterFactories.size() + platform.defaultConverterFactoriesSize());

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

      return new Retrofit(
          callFactory,
          baseUrl,
          unmodifiableList(converterFactories),
          unmodifiableList(callAdapterFactories),
          callbackExecutor,
          validateEagerly);
    }
Retrofit创建过程:

创建一个Retrofit实例,通过建造者模式设置并初始成员变量:

defaultCallAdapterFactory内部:
  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);
      }
    }
  }

最终使用了MainThreadExecutor作为结果回传执行,即用了主线程的handler作为请求结果传递,使用handler.post即从子线程中向主线程发送消息。

retrofit.create():

在创建好网络请求服务接口MyService类后,调用retrofit.create(MyService::class.java),这个方法是Retrofit的核心,内部采用动态代理,将自定义的网络请求接口转换成一个ServiceMethod对象,ServiceMethod就是咱们Retrofit中的具体请求对象,里面封装了网络请求所必须的全部信息,包括请求方法、url、请求头、请求体等网络配置参数。

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, 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);
            }
            return loadMethodHandler(method).invoke(args);
          }
        });
  }


在ServiceMethod的build方法中,获取请求返回类型,通过反射将各种请求类型,请求参数的okhttp请求简化的封装。

然后将得到的ServiceMethod传给OkHttpCall,创建OkHttpCall。

创建OkHttpCall对象
OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);

OkHttpCall部分代码:

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

然后调用OkhttpCall的enqueue方法去执行,方法内部调用createRawCall()将serviceMethod转为okhttp的call类型,去执行okhttp的enqueue方法,去执行网络请求。然后将请求的结果让CallbackExecutor去做线程切换,通过CallBack去实现成功、失败的回调。

GsonConverterFactory
public final class GsonConverterFactory extends Converter.Factory {
  /**
   * Create an instance using a default {@link Gson} instance for conversion. Encoding to JSON and
   * decoding from JSON (when no charset is specified by a header) will use UTF-8.
   */
  public static GsonConverterFactory create() {
    return create(new Gson());
  }

  /**
   * Create an instance using {@code gson} for conversion. Encoding to JSON and
   * decoding from JSON (when no charset is specified by a header) will use UTF-8.
   */
  public static GsonConverterFactory create(Gson gson) {
    return new GsonConverterFactory(gson);
  }

  private final Gson gson;

  private GsonConverterFactory(Gson gson) {
    if (gson == null) throw new NullPointerException("gson == null");
    this.gson = gson;
  }
}

GsonConverterFactory.creat()是创建了一个含有Gson对象实例的GsonConverterFactory,并返回给addConverterFactory()

Retrofit中addConverterFactory代码:

    public Builder addConverterFactory(Converter.Factory factory) {
      converterFactories.add(checkNotNull(factory, "factory == null"));
      return this;
    }

放入到数据转换器工厂converterFactories里,可用retrofit的默认Gson来解析,也可以自定义解析器。

CallAdapter

定义:网络请求执行器(Call)的适配器。

addCallAdapterFactory(RxJavaCallAdapterFactory.create())

把response封装成rxjava的Observeble,然后进行流式操作。

将response适配为Observable对象:

  static final class ResultCallAdapter implements CallAdapter<Observable<?>> {
    private final Type responseType;

    ResultCallAdapter(Type responseType) {
      this.responseType = responseType;
    }

    @Override public Type responseType() {
      return responseType;
    }

    @Override public <R> Observable<Result<R>> adapt(Call<R> call) {
      return Observable.create(new CallOnSubscribe<>(call)) //
          .map(new Func1<Response<R>, Result<R>>() {
            @Override public Result<R> call(Response<R> response) {
              return Result.response(response);
            }
          })
          .onErrorReturn(new Func1<Throwable, Result<R>>() {
            @Override public Result<R> call(Throwable throwable) {
              return Result.error(throwable);
            }
          });
    }
  }
整个流程总结图:

参考:
Android:手把手带你 深入读懂 Retrofit 2.0 源码
Retrofit2源码分析:架构全面解析

举报

相关推荐

0 条评论