Retrofit源码分析

Retrofit

Retrofit 是一个 RESTful 的 HTTP 网络框架封装,底层使用的 OkHttp.


基本使用
引入依赖
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'

创建一个接口作为网络的请求集合,在方法上用注解进行配置
public interface GitHubService {
  @GET("users/{user}/repos")
  Call<List<Repo>> listRepos(@Path("user") String user);
}

使用 Retrofit 创建出接口的实例
Retrofit retrofit = new Retrofit.Builder()
    .baseUrl("https://api.github.com/")
 		.addConverterFactory(GsonConverterFactory.create())
    .build();

GitHubService service = retrofit.create(GitHubService.class);

调用接口的对应方法,就创建网络请求对象 Call
Call<List<Repo>> repos = service.listRepos("octocat");

使用 Call.enqueue() 或 Call.execute() 发起网络请求
repos.enqueue(new Callback<List<Repo>>() {
    @Override
    public void onResponse(Call<List<Repo>> call, Response<List<Repo>> response) {
        Log.e("TAG", "onResponse:" + response.body().get(0).getName());
    }

    @Override
    public void onFailure(Call<List<Repo>> call, Throwable t) {
      
    }
});

源码分析
Retrofit 实例创建

Retrofit 实例是通过建造者模式创建的

// Retrofit类
public final class Retrofit {
  // 网络请求配置对象(对接口中的方法注解解析后得到的对象)
  // 缓存,存储网络请求中的相关配置,请求的方法,数据转换器,适配器,基地址
  private final Map<Method, ServiceMethod<?>> serviceMethodCache = new ConcurrentHashMap<>();

  final okhttp3.Call.Factory callFactory;// 网络请求器的工厂
  final HttpUrl baseUrl;
  final List<Converter.Factory> converterFactories;// 数据转换器工厂集合
  final List<CallAdapter.Factory> callAdapterFactories;// 网络请求适配器工厂集合
  final @Nullable Executor callbackExecutor;// 回调方法执行器
  final boolean validateEagerly;// 是否提前对接口中的方法注解进行验证
  
  Retrofit(
      okhttp3.Call.Factory callFactory,
      HttpUrl baseUrl,
      List<Converter.Factory> converterFactories,
      List<CallAdapter.Factory> callAdapterFactories,
      @Nullable Executor callbackExecutor,
      boolean validateEagerly) {
    this.callFactory = callFactory;
    this.baseUrl = baseUrl;
    this.converterFactories = converterFactories; // Copy+unmodifiable at call site.
    this.callAdapterFactories = callAdapterFactories; // Copy+unmodifiable at call site.
    this.callbackExecutor = callbackExecutor;
    this.validateEagerly = validateEagerly;
  }
  ...
    
  // 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;
    
    Builder(Platform platform) {
      this.platform = platform;// 平台类型对象
    }

    public Builder() {
      this(Platform.get());
    }
    
    // 添加url地址
    public Builder baseUrl(URL baseUrl) {
      Objects.requireNonNull(baseUrl, "baseUrl == null");
      return baseUrl(HttpUrl.get(baseUrl.toString()));
    }
    
    // 添加数据转化器,可以把返回的数据解析成指定的类型
    public Builder addConverterFactory(Converter.Factory factory) {
      converterFactories.add(Objects.requireNonNull(factory, "factory == null"));
      return this;
    }
    
    // 添加网络请求适配器,CallAdatper对原始Call进行再次封装,如Call<R>到Observable<R>
    public Builder addCallAdapterFactory(CallAdapter.Factory factory) {
      callAdapterFactories.add(Objects.requireNonNull(factory, "factory == null"));
      return this;
    }
    
    ...
    
    public Retrofit build() {
      ...
			
      okhttp3.Call.Factory callFactory = this.callFactory;// 网络请求执行器
      if (callFactory == null) {
        callFactory = new OkHttpClient();
      }

      Executor callbackExecutor = this.callbackExecutor;
      if (callbackExecutor == null) {
        // 如果没指定,则默认使用Platform检测环境时的默认callbackExecutor
        // 即Android默认的callbackExecutor
        callbackExecutor = platform.defaultCallbackExecutor();
      }

      // 配置网络请求适配器工厂
      List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
      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);
    }
  }
}

平台类型 Platform

// Platform 类型
class Platform {
  private static final Platform PLATFORM = findPlatform();

  static Platform get() {
    return PLATFORM;
  }

  private static Platform findPlatform() {
    return "Dalvik".equals(System.getProperty("java.vm.name"))
        ? new Android() //
        : new Platform(true);
  }
 	...
    
  // 用于接收服务器返回数据后进行线程切换在主线程显示结果
  static final class Android extends Platform {
    Android() {
      super(Build.VERSION.SDK_INT >= 24);
    }

    @Override
    public Executor defaultCallbackExecutor() {
      return new MainThreadExecutor();
    }

    // 回调方法执行器
    static final class MainThreadExecutor implements Executor {
      private final Handler handler = new Handler(Looper.getMainLooper());

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

数据转换器工厂 GsonConverterFactory

// GsonConverterFactory.crate() 创建了一个含有 Gson 对象实例
public final class GsonConverterFactory extends Converter.Factory {
 
  public static GsonConverterFactory create() {
    return create(new Gson());
  }

  @SuppressWarnings("ConstantConditions") // Guarding public API nullability.
  public static GsonConverterFactory create(Gson gson) {
    if (gson == null) throw new NullPointerException("gson == null");
    return new GsonConverterFactory(gson);
  }
  ...

}

Retrofit 使用建造者模式通过 Builder 类创建了一个 Retrofit 对象,配置了:

  • 平台类型对象 (Platform)
  • url地址(baseUrl)
  • 网络请求工厂(callFactory)
  • 网络请求适配器的集合(adpterFactories)
  • 数据转换器工厂集合(converterFactories)
  • 回调方法执行器(callbackExector)

请求接口实例创建

Retrofit 是通过 外观模式 和 代理模式 使用 Retrofit.create() 方法创建的网络请求接口的实例,从而使得接口 中配置的方法变得可用,这是 Retrofit 代码接口的核心。

外观模式:定义一个统一的接口,外部通过该接口对子系统里的其他接口进行访问

代理模式:通过访问代理对象的方式间接访问目标对象


Retrofit.create() 方法内部,使用的是 Proxy.newProxyInstance() 方法来创建 接口 的实例。这个方法内部会为入参的多个 inteface 创建了一个对象,这个对象实现了所有 interface 的每个方法,并且每个方法的实现都是雷同的:调用对象实例内部的一个 InvocationHandler 成员变量的 invoke() 方法,并把对应的方法信息传递进去。

因此 InvocationHandler 中的 invoke() 方法中的逻辑,就是执行接口中的方法。


// Retrofit类
public <T> T create(final Class<T> service) {
  validateServiceInterface(service);// 验证接口
  return (T)
    	// 创建了网络请求接口的动态代理对象
      Proxy.newProxyInstance(
          service.getClassLoader(),// 类加载器
          new Class<?>[] {service},// 要创建哪些接口
          new InvocationHandler() {// 当接口的方法触发,会间接调用到 InvocationHandler 的 invoke 方法
            private final Platform platform = Platform.get();
            private final Object[] emptyArgs = new Object[0];

            @Override
            public @Nullable 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);// 如果是Object类,直接触发方法
              }
              args = args != null ? args : emptyArgs;
              return platform.isDefaultMethod(method)
                  ? platform.invokeDefaultMethod(method, service, proxy, args)// 平台默认方法,直接触发方法
                  : loadServiceMethod(method).invoke(args);// 核心是这行代码,加载接口的方法,并执行
            }
          });
}

ServiceMethod 的创建

loadServiceMethod(method),这行代码负责读取接口中原方法的信息(包括返回值类型、方法注解、参数类型、参数注解),并把这些信息做初步分析,最后实际返回的是一个 CallAdapted .

// Retrofit类
ServiceMethod<?> loadServiceMethod(Method method) {
  ServiceMethod<?> result = serviceMethodCache.get(method);
  if (result != null) return result;

  synchronized (serviceMethodCache) {
    result = serviceMethodCache.get(method);
    if (result == null) {
      result = ServiceMethod.parseAnnotations(this, method);// 关键是这句
      serviceMethodCache.put(method, result);
    }
  }
  return result;
}

// ServiceMethod类
// ServiceMethod.parseAnnotations
abstract class ServiceMethod<T> {
  static <T> ServiceMethod<T> parseAnnotations(Retrofit retrofit, Method method) {
    // 解析方法上的注解
    RequestFactory requestFactory = RequestFactory.parseAnnotations(retrofit, method);

    Type returnType = method.getGenericReturnType();
    if (Utils.hasUnresolvableType(returnType)) {
      throw methodError(
          method,
          "Method return type must not include a type variable or wildcard: %s",
          returnType);
    }
    if (returnType == void.class) {
      throw methodError(method, "Service methods cannot return void.");
    }

    return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);// 关键是这句
  }

  abstract @Nullable T invoke(Object[] args);
}

// HttpServiceMethod类
// HttpServiceMethod.parseAnnotations
static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations(
      Retrofit retrofit, Method method, RequestFactory requestFactory) {
  
  	...
    CallAdapter<ResponseT, ReturnT> callAdapter =
        createCallAdapter(retrofit, method, adapterType, annotations);
  	...
      
    if (!isKotlinSuspendFunction) {
      return new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter);// 关键是这句
    } else if (continuationWantsResponse) {
      //noinspection unchecked Kotlin compiler guarantees ReturnT to be Object.
      return (HttpServiceMethod<ResponseT, ReturnT>)
          new SuspendForResponse<>(
              requestFactory,
              callFactory,
              responseConverter,
              (CallAdapter<ResponseT, Call<ResponseT>>) callAdapter);
    } else {
      //noinspection unchecked Kotlin compiler guarantees ReturnT to be Object.
      return (HttpServiceMethod<ResponseT, ReturnT>)
          new SuspendForBody<>(
              requestFactory,
              callFactory,
              responseConverter,
              (CallAdapter<ResponseT, Call<ResponseT>>) callAdapter,
              continuationBodyNullable);
    }
  }

OkHttpCall 的创建

invoke(args) 方法的调用,会触发 OkHttpCall 的创建。

// HttpServiceMethod类
@Override
final @Nullable ReturnT invoke(Object[] args) {
  Call<ResponseT> call = new OkHttpCall<>(requestFactory, args, callFactory, responseConverter);
  return adapt(call, args);// 会调用到 CallApter 的 adapter 方法
}

OkHttpCall 是 retrofit2.Call 的子类,OkHttpCall 的创建将 ServiceMethod 解读到信息(RequestFactory、OkHttpClient 和 ResponseConverter)封装进 OkHttpCall,OkHttpCall 在 enqueue() 方法被调用的时候,利用 RequestFactory 和 OkHttpClient 来创建一个 okhttp3.Call 对象,并调用 okhttp3.Call 来进行网络请求的发起,然后利用 ResponseConverter 对结果进行预处理之后,交回给 Retrofit 的 Callback .


适配器的处理

adapt(call, args) 方法调用会触发到 callAdapter.adapt(call) 的调用

callAdapter.adapt(call);

这个⽅法会使⽤⼀个 CallAdapter 对象来把 OkHttpCall 对象进⾏转换,⽣成⼀个新的对象。默认情况下,返回的是⼀个 ExecutorCallbackCall,它的作⽤是把操作切回主线程后再交给 Callback .

如果有自定义的 CallAdapter,这里也可以生成别的类型的对象,例如 RxJava 的 Observable,来让 Retrofit 和 RxJava 结合使用。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值