Retrofit 2.9.0 源码解析

本文深入解析Retrofit 2.9.0的源码,揭示如何通过声明实现网络请求,支持协程的原理。内容涵盖Retrofit实例创建、网络请求接口的实现,详细分析了创建对象、配置baseUrl、Gson转换、建造者模式以及外观模式、动态代理等设计模式的应用。
摘要由CSDN通过智能技术生成

Retrofit 2.9.0 源码解析

1、前言

在平时开发过程中,我们经常会用到Retrofit+OkHttp作为我们的网络请求框架;其简洁易用的特性,为我们的开发工作带来很大的便利性。
那么在使用过程中有没有以下疑问呢?

a. Retrofit是如何通过Interface Service 声明来实现网络请求的;
b. Retrofit 是如何支持Kotlin协程的(即如何使用suspend来实现将Call<Response>直接转换为Response的呢);
c. Retrofit在设计中使用了哪些设计模式呢;

2、Retrofit是如何通过Interface Service 声明来实现网络请求的

我们先来看一下Retrofit的初始化和请求示例:

//1. 创建retrofit 实例,这里使用到了建造者模式
 Retrofit retrofit =
        new Retrofit.Builder()
            .baseUrl(API_URL)
            .addConverterFactory(GsonConverterFactory.create())
            .build();
	//2. 通过retrofit 实例,创建Service实例,这里使用到了外观模式,策略模式,
    GitHub github = retrofit.create(GitHub.class);

    // 3. 通过Service实例获取请求实例Call
    Call<List<Contributor>> call = github.contributors("square", "retrofit");
	//4. 通过请求实例 Call 发送请求,包含两种方式,异步和同步
	//4.1 同步发送
	List<Contributor> contributors = call.execute().body();
	//4.2 异步发送
	call.enqueue(new Callback<List<Contributor>>() {
   
      @Override
      public void onResponse(Call<List<Contributor>> call, Response<List<Contributor>> response) {
   
        //request success
        List<Contributor> contributors = response.body();
      }

      @Override
      public void onFailure(Call<List<Contributor>> call, Throwable t) {
   
        //request fail
      }
    });

2.1 创建retrofit 实例

Retrofit retrofit =
        new Retrofit.Builder()  //步骤1
            .baseUrl(API_URL)	//步骤2
            .addConverterFactory(GsonConverterFactory.create())	//步骤3
            .build();		//步骤4

可以看到retrofit实例的创建,可以分为4步,接下来我们具体看一下这4步涉及到的逻辑

2.1.1 创建Retrofit.Builder对象
///Builder 类
public static final class Builder {
   
    private final Platform platform;
    private @Nullable okhttp3.Call.Factory callFactory;
    private @Nullable HttpUrl baseUrl;
    private final List<Converter.Factory> converterFactories = new ArrayList<>();
    private final List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>();
    private @Nullable Executor callbackExecutor;
    private boolean validateEagerly;

	//步骤1
	//默认无参的构造方法
 	public Builder() {
   
      this(Platform.get());
     //通过this调用了有参的构造方法
     //通过Platform.get() 获取了Platform 对象并传入
    }
    
    Builder(Platform platform) {
   
      this.platform = platform;
    }
  
	... //
	
}
//步骤2 
//Platform 类中,通过静态get()方法,获取平台对象。
///Platform 类
class Platform {
   
  private static final Platform PLATFORM = findPlatform();

  static Platform get() {
   
    return PLATFORM;
  }

	//步骤3
  private static Platform findPlatform() {
   
  //通过`findPlatform()`方法来根据虚拟机属性,创建平台对象。在Android中的虚拟机名称为`Dalvik`,则会创建Android平台对象,否则创建支持java8的平台对象。
    return "Dalvik".equals(System.getProperty("java.vm.name"))
        ? new Android() //
        : new Platform(true);
  }

  
  	//步骤4
  	//Android 平台类,继承自Platform,
	///Android 类
  static final class Android extends Platform {
   
    Android() {
   
      super(Build.VERSION.SDK_INT >= 24);
    }

    @Override
    public Executor defaultCallbackExecutor() {
   
    //重写`defaultCallbackExecutor`方法,返回`MainThreadExecutor`对象,用于在服务器返回数据后,将线程切换到主线程展示结果。
      return new MainThreadExecutor();
    }

    @Nullable
    @Override
    Object invokeDefaultMethod(
        Method method, Class<?> declaringClass, Object object, Object... args) throws Throwable {
   
      if (Build.VERSION.SDK_INT < 26) {
   
        throw new UnsupportedOperationException(
            "Calling default methods on API 24 and 25 is not supported");
      }
      return super.invokeDefaultMethod(method, declaringClass, object, args);
    }
	//步骤5
	//装饰类(装饰模式),内部创建了Android 主线程对应的Handler,执行时通过该Handler来切换到主线程
	///	MainThreadExecutor 类
    static final class MainThreadExecutor implements Executor {
   
    	//创建Handler,并绑定主线程Looper
      private final Handler handler = new Handler(Looper.getMainLooper());

      @Override
      public void execute(Runnable r) {
   
      //将Runnable切换到主线程执行
        handler.post(r);
      }
    }
  }
}
  1. 通过默认无参的构造方法,在构造方法中通过this调用了有参的构造方法,并通过Platform.get()方法传入参数
  2. Platform 类中,通过静态get()方法,获取平台对象。
  3. 通过findPlatform()方法来根据虚拟机属性,创建平台对象。在Android中的虚拟机名称为Dalvik,则会创建Android平台对象,否则创建支持java8的平台对象。
  4. Android 平台类,继承自Platform,并重写defaultCallbackExecutor方法,返回MainThreadExecutor对象,用于在服务器返回数据后,将线程切换到主线程展示结果。
  5. MainThreadExecutor类是一个装饰类(装饰模式),内部创建了Android 主线程对应的Handler,执行时通过该Handler来切换到主线程。
2.1.2 baseUrl(API_URL)
//Retrofit.Builder类

    public Builder baseUrl(String baseUrl) {
   
    	//baseUrl判空处理
      Objects.requireNonNull(baseUrl, "baseUrl == null");
      //将baseUrl解析Okhttp请求所需要的HttpUrl对象。
      return baseUrl(HttpUrl.get(baseUrl));
    }
    
	public Builder baseUrl(HttpUrl baseUrl) {
   
      Objects.requireNonNull(baseUrl, "baseUrl == null");
      //将baseUrl路径根据/进行分割,并判断最后是否以/结尾,不是则抛出异常
      List<String> pathSegments = baseUrl.pathSegments();
      if (!"".equals(pathSegments.get(pathSegments.size() - 1))) {
   
        throw new IllegalArgumentException("baseUrl must end in /: " + baseUrl);
      }
      this.baseUrl = baseUrl;
      return this;
    }

总结:baseUrl()用于配置Retrofit类的网络请求url地址:将传入的String类型url转化为适合OKhttp的HttpUrl类型的url

2.1.3 addConverterFactory(GsonConverterFactory.create())
///Retrofit.Builder类

	/**
	* 添加一个数据转换器工厂
	*/
    public Builder addConverterFactory(Converter.Factory factory) {
   
      converterFactories.add(Objects.requireNonNull(factory, "factory == null"));
      return this;
    }

    /**
     * 添加Call 适配器工厂
     */
    public Builder addCallAdapterFactory(CallAdapter.Factory factory) {
   
      callAdapterFactories.add(Objects.requireNonNull(factory, "factory == null"));
      return this;
    }

   /**
   	* 添加服务器返回数据后的线程转换回调执行器
   	*/
    public Builder callbackExecutor(Executor executor) {
   
      this.callbackExecutor = Objects.requireNonNull(executor, "executor == null");
      return this;
    }

/// GsonConverterFactory 类
public final class GsonConverterFactory extends Converter.Factory {
   
  
  public static GsonConverterFactory create() {
   
  	 创建一个Gson对象
    return create(new Gson());
  }

 
  @SuppressWarnings("ConstantConditions") // Guarding public API nullability.
  public static GsonConverterFactory create(Gson gson) {
   
    if (gson == null) throw new NullPointerException("gson == null");
     创建了一个含有Gson对象实例的GsonConverterFactory
    return new GsonConverterFactory(gson);
  }

  private final Gson gson;

  private GsonConverterFactory(Gson gson
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值