Retrofit源码学习三:Retrofit源码详解一

目录

系列文章:

Retrofit优点在哪里?

网络通讯八步骤:

七个关键成员变量解析:

builder构建者模式解析:

Platform.java

baseUrl()方法解析:

.addConverterFactory(GsonConverterFactory.create())

.addCallAdapterFactory(RxJavaCallAdapterFactory.create())

.build();


系列文章:

Retrofit源码学习一:Retrofit介绍

Retrofit源码学习二:代理模式

Retrofit源码学习三:Retrofit源码详解一

Retrofit源码学习四:Retrofit源码详解二

Retrofit源码学习五:Retrofit中同步、异步请求解析

Retrofit源码学习六:框架中的设计模式

Retrofit优点在哪里?

跟之前的类似框架相比,它采用了大量的设计模式,将我们网络请求的一些功能模块进行了完全地解耦,这就让我们的网络请求工作变得更加简单、流畅、清晰。

网络通讯八步骤:

1、创建Retrofit实例

2、定义一个网络请求接口并为接口中的方法添加注解

3、通过 动态代理 生成 网络请求对象

4、通过 网络请求适配器 将 网络请求对象 进行平台适配

5、通过 网络请求执行器 发送网络请求

6、通过 数据转换器 解析数据

7、通过 回调执行器 切换线程

8、用户在主线程处理返回结果

七个关键成员变量解析:

Retrofit.java{

    //LinkedHashMap  Method是请求方法
    //serviceMethodCache 主要用于缓存的一些网络信息的配置、网络请求方法、网络适配器、网络转换器等
	private final Map<Method, ServiceMethod> serviceMethodCache = new LinkedHashMap<>();

    //请求网络的okhttp的工厂,用于生产okhttpClient,默认值也是okhttpClient
	private final okhttp3.Call.Factory callFactory;

    //网络请求url的基地址
	private final HttpUrl baseUrl;

    //数据转换器工厂集合  默认使用的是GsonConverterFactory
    //Converter转换器:对我们请求后返回的response进行转换,转换成我们能够使用的java对象
    //1、该工厂集合放置Converter  2、该工厂集合生产Converter
	private final List<Converter.Factory> converterFactories;

    //网络请求适配器工厂集合  
    //Adapter适配器:把我们的Call对象转换成其他类型,比如,如果想支持rxjava的话,就可以把Call对象
    //转换成为rxjava的Call对象
    //1、该工厂集合放置Adapter  2、该工厂集合生产Adapter
	private final List<CallAdapter.Factory> adapterFactories;

    //异步回调执行器:用于执行异步回调  默认是MainThreadExecutor 
	private final Executor callbackExecutor;

    //标记位 是否需要立即解析我们接口中的方法
	private final boolean validateEagerly;

}

builder构建者模式解析:

这个Builder是Retrofit的公开内部类,有以下七个成员变量,可以看到,除了第一个成员不同外,其他都相同

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

    Builder(Platform platform) {
      this.platform = platform;
      converterFactories.add(new BuiltInConverters());
    }

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

我们先看无参构造方法,里面调用了Platform,我们来看这个类

Platform.java

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) {
    }
    try {
      Class.forName("org.robovm.apple.foundation.NSObject");
      return new IOS();
    } catch (ClassNotFoundException ignored) {
    }
    return new Platform();
  }

从这段代码我们可以看出,Retrofit能够适配三个不同的平台:Android、Java8 和 IOS ,我们只关心Android

static class Android extends Platform {

    //callbackExecutor 的默认值也是 MainThreadExecutor
    //主要作用:从子线程切换到主线程,同时,它可以在主线程中实行回调方法
    @Override 
    public Executor defaultCallbackExecutor() {
      return new MainThreadExecutor();
    }

    //创建默认的网络适配器工厂
    @Override 
    CallAdapter.Factory defaultCallAdapterFactory(Executor callbackExecutor) {
      return new ExecutorCallAdapterFactory(callbackExecutor);
    }
    
    //MainThreadExecutor 绑定的是主线程
    static class MainThreadExecutor implements Executor {
      //内部Handler 绑定的 Looper 是 MainLooper
      private final Handler handler = new Handler(Looper.getMainLooper());

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

 接下来我们看有参构造方法:

    Builder(Platform platform) {
      this.platform = platform;
      converterFactories.add(new BuiltInConverters());
    }

 可以看到,第一,初始化platform;第二,在数据转换器工厂集合中converterFactories添加了BuiltInConverters(Retrofit内置,提供的数据转换器工厂)

baseUrl()方法解析:

public Builder baseUrl(String baseUrl) {
      checkNotNull(baseUrl, "baseUrl == null");
      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");
      List<String> pathSegments = baseUrl.pathSegments();
      //baseUrl 必须以“/” 为结尾,否则报异常
      if (!"".equals(pathSegments.get(pathSegments.size() - 1))) {
        throw new IllegalArgumentException("baseUrl must end in /: " + baseUrl);
      }
      this.baseUrl = baseUrl;
      return this;
}

其实,这个方法很简单,就是将string类型的url转化为HttpUrl类型的url。

往下面讲,

.addConverterFactory(GsonConverterFactory.create())

设置数据解析器

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

addConverterFactory这个方法很简单,就是将我们传入的转换器工厂添加到集合converterFactories中。

我们来看这个GsonConverterFactory.create()

public final class GsonConverterFactory extends Converter.Factory {
    
     public static GsonConverterFactory create() {
        return create(new Gson());
     }

     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.create()这个方法就是创建了一个含有Gson对象实例的GsonConverterFactory

.addCallAdapterFactory(RxJavaCallAdapterFactory.create())

支持RxJava平台

public Builder addCallAdapterFactory(CallAdapter.Factory factory) {
      adapterFactories.add(checkNotNull(factory, "factory == null"));
      return this;
    }

这个很简单,也是将我们传入的适配器工厂添加到集合adapterFactories中。

我们来看这个RxJavaCallAdapterFactory.create()

public final class RxJavaCallAdapterFactory extends CallAdapter.Factory {
    
    public static RxJavaCallAdapterFactory create() {
        return new RxJavaCallAdapterFactory(null);
    }

    //rxjava中的调度器
    private final Scheduler scheduler;

    private RxJavaCallAdapterFactory(Scheduler scheduler) {
        this.scheduler = scheduler;
    }

}

通过以上代码,我们可以看出,调用RxJavaCallAdapterFactory.create()这个方法就是创建了一个含有rxjava中的调度器Scheduler 对象实例的RxJavaCallAdapterFactory。需要注意的是调度器Scheduler 对象实例此处为null对象。

接下来就到最后一步build方法了

Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://www.baidu.com/")//设置网络请求的URL地址
                .addConverterFactory(GsonConverterFactory.create())//设置数据解析器
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())//支持RxJava平台
                .build();

.build();

public Retrofit build() {
      if (baseUrl == null) {
        throw new IllegalStateException("Base URL required.");
      }

      okhttp3.Call.Factory callFactory = this.callFactory;
       if (callFactory == null) {
            //印证了前面所说 callFactory 默认为 OkHttpClient
            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));

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

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

build方法主要作用就是通过内部类 Builder 将 Retrofit类 当中的所有成员变量配置完毕后,新建一个Retrofit对象。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值