通过源码,分析Retrofit2的整体执行流程

RetrofitAndroid应用层最为广泛的网络请求框架之一。
它通过动态代理、工厂模式、Builder模式等设计模式,对Okhttp进行了巧妙封装。
本文,将对Retrofit2 源码进行分析。若无特殊说明,源码api为2.7.2

一.动态代理

在使用Retrofit 时,我们先定义一个接口,然后通过调用retrofit.create方法,得到一个接口的实例,最后通过该实例执行我们的操作。

Retrofit在设计过程中,有一个很重要的知识点,动态代理.

在正式学习Retrofit源码之前,先对Java中的动态代理进行了解。

先定义一个接口:

代码片1
public interface ITest {
   

    @GET("/test")
    public void add(int a, int b);
}

通过动态代码的代码如下:

代码片2
   ITest iTest = (ITest) Proxy.newProxyInstance(ITest.class.getClassLoader(),
                new Class<?>[]{
   ITest.class}, new InvocationHandler() {
   
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
   
                Integer a = (Integer) args[0];
                Integer b = (Integer) args[1];
                System.out.println("方法名:" + method.getName());
                System.out.println("参数:" + a + " , " + b);

                GET get = method.getAnnotation(GET.class);
                System.out.println("注解:" + get.value());
                return null;
            }
        });

   iTest.add(3, 5);

输出结果如下:

I/System.out: 方法名:add
I/System.out: 参数:3 , 5
I/System.out: 注解:/test

可以看到通过 Proxy.newProxyInstance 产生的代理类,当调用接口的任何方法时,都会调用 Proxy#InvocationHandler 方法,在这个方法中可以拿到传入的参数、注解等。

二.Retrofit源码分析

代码片3
       Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("https://api.github.com/")
                .addConverterFactory(GsonConverterFactory.create(mGson))
                .build();

        GitHubService service = retrofit.create(GitHubService.class);
        Call<List<Repo>> call = service.listRepos("gaolhjy");
        call.enqueue(new Callback<List<Repo>>() {
   
            @Override
            public void onResponse(Call<List<Repo>> call, Response<List<Repo>> response) {
   
                Log.e(TAG, "onResponse: " + "success");
            }

            @Override
            public void onFailure(Call<List<Repo>> call, Throwable t) {
   
                Log.e(TAG, "onResponse: " + "onFailure");
            }
        });

上述代码,是比较典型的使用Retrofit进行的网络请求的写法。

(一) Retrofit的创建过程

代码片4
Retrofit retrofit = new Retrofit.Builder()    //1.创建builder
      .baseUrl("https://api.github.com/")     //2.配置builder
      .build();                              //3、创建Retrofit实例

1.创建builder

代码片5
public static final class Builder {
   
   
    private final Platform platform;    //运行Retrofit的平台
    //省略部分代码
   
   //根据Platform构造
    Builder(Platform platform) {
   
      this.platform = platform;
    }

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

    //根据另外一个Retrofit构造
    Builder(Retrofit retrofit) {
   
      platform = Platform.get();
      callFactory = retrofit.callFactory;
      baseUrl = retrofit.baseUrl;
      //省略部分代码
     }

okhttp一样,Retrofit的实例化也是采用builder模式。

我们使用了无参的构造函数来创建BuilderBuilder的无参构造函数首先通过Platform.get()获取了一个Platform实例赋值给了platform字段,前面提到过Retrofit是有Platform的概念,Retrofit支持javaAndroid平台。

我们来看一下Platform类.

代码片6
class Platform {
   
  
  //单例
  private static final Platform PLATFORM = findPlatform();
  
  //返回Platform 对象
  static Platform get() {
   
    return PLATFORM;
  }

  private static Platform findPlatform() {
   
    try {
   
      //android.os.Build这个类是Android独有的
      //这里要求JVM查找并加载Build.class对象
      Class.forName("android.os.Build");
      if (Build.VERSION.SDK_INT != 0) {
   
        //如果是Android平台,创建一个Android实例返回,Android继承自Platform
        return new Android();
      }
    } catch (ClassNotFoundException ignored) {
   
      //找不到android.os.Build,会抛出异常,捕捉,继续执行
    }
    //返回默认Platform实例,并传hasJava8Types为true
    return new Platform(true);
  }

  private final boolean hasJava8Types;

  Platform(boolean hasJava8Types) {
   
    this.hasJava8Types = hasJava8Types;
  }

  //返回默认的线程切换执行器
  @Nullable Executor defaultCallbackExecutor() {
   
    return null;
  }

  //返回默认的网络请求适配器工厂
  List<? extends CallAdapter.Factory> defaultCallAdapterFactories(
      @Nullable Executor callbackExecutor) {
   
    DefaultCallAdapterFactory executorFactory = new DefaultCallAdapterFactory(callbackExecutor);
    return hasJava8Types
        ? asList(CompletableFutureCallAdapterFactory.INSTANCE, executorFactory)
        : singletonList(executorFactory);
  }

  int defaultCallAdapterFactoriesSize() {
   
    return hasJava8Types ? 2 : 1;
  }

  List<? extends Converter.Factory> defaultConverterFactories() {
   
    return hasJava8Types
        ? singletonList(OptionalConverterFactory.INSTANCE)
        : emptyList();
  }

  int defaultConverterFactoriesSize() {
   
    return hasJava8Types ? 1 : 0;
  }

  boolean isDefaultMethod(Method method) {
   
    return hasJava8Types && method.isDefault();
  
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值