Retrofit 整理

1.Retrofit

Retrofit是基于OkHttp框架来实现请求的,它是基于OkHttp框架的一套封装,利用动态代理实现网络请求,支持Gson、RxJava的适配。

 

2.使用Retrofit时gradle配置

implementation 'com.squareup.okhttp3:okhttp:4.8.1'

implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.5.0'
implementation 'com.squareup.retrofit2:adapter-rxjava2:2.7.2'

implementation 'com.google.code.gson:gson:2.8.6'

implementation 'io.reactivex.rxjava3:rxjava:3.0.0'
implementation 'io.reactivex.rxjava3:rxandroid:3.0.0'

 

3.Retrofit简单使用

3.1创建接口类

interface GitHubApiService {

    @GET("wxarticle/chapters/json")
    fun getListChapters(): Call<InfoData>

}

3.2使用Retrofit执行网络请求

//初始化 一个 Retrofit对象
val retrofit = Retrofit.Builder()
    .baseUrl("https://www.wanandroid.com/")
    .addConverterFactory(GsonConverterFactory.create())
    .build()

//创建出 GithubApiService对象
val service = retrofit.create(GitHubApiService::class.java)
//返回一个Call对象
val getChapterInfo = service.getListChapters()
//调用enqueue 方法在回调方法里处理结果
getChapterInfo.enqueue(object : Callback<InfoData> {
    override fun onFailure(call: Call<InfoData>, t: Throwable) {
        t.printStackTrace()
    }

    override fun onResponse(call: Call<InfoData>, response: Response<InfoData>) {
       Log.v("respose", response.toString())
    }

})

 主要分为几步:

(1)通过Builder模式创建Retrofit实例;

(2)通过动态代理创建接口的实例;

(3)通过接口的实例获取到网络请求的操作类Call;

(4)通过Call来执行网络请求;

 

4.Retrofit详细设计

4.1 Retroft对象创建流程

1.在Builder的构造函数中,会调用Platform的get方法返回一个平台实例,正常是Android平台。Platform主要是用于适配不同的平台,用于获取默认的Executor,请求适配器工厂类CallAdapterFactory,数据转换工厂类ConverterFactory等;

static final class Android extends Platform {
  Android() {
    super(Build.VERSION.SDK_INT >= 24);
  }

  @Override
  public Executor defaultCallbackExecutor() {
    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);
  }

  static final class MainThreadExecutor implements Executor {
    private final Handler handler = new Handler(Looper.getMainLooper());

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

 

2.上面的MainThreadExecutor,将任务post到主线程中执行。

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;
}

3.根据hasJava8Types初始化获取默认的CallAdapter.Factory,用于创建CallAdapter;获取默认的数据转换工厂ConverterFactory,用于创建转换器Converter;

 

4.2接口类实例创建过程

 

1.验证我们定义的接口类的合法性。

2.通过动态代理,来返回 接口类的实例。

  • 获取一个 ClassLoader 对象
  • GitHubApiService 的字节码对象传到数组中去,也即是我们要代理的具体接口。
  • InvocationHandler 的 invoke 是关键,接口类实例的方法在调用时,会执行 InvocationHandler 的invoke的方法体。

 

4.3Call 对象的创建过程

1.当接口类的getListChapters方法执行的时候,会出发InvocationHandler的invoke方法调用。

2.在invoke方法中,首先判断有代理类是否是继承 Object 类,所以如果是 Object.class 走默认调用它的方法。(这个自己不太理解为啥会有这个判断)

如果不是,并且是Android平台,会调用loadServiceMethod方法。

3.在loadServiceMethod方法中,从 ConcurrentHashMap 中取一个 ServiceMethod 如果存在直接返回。否则通过 ServiceMethod.parseAnnotations(this, method)方法创建一个 ServiceMethod 对象,创建完会加入到 ConcurrentHashMap 中。

4.在ServiceMethod的parseAnnotations中,首先执行RequestFactory的parseAnnotations方法。RequestFactory类主要封装网络请求的大多数信息,例如method,headers,httpMethod等等。通过RequestFactory.parseAnnotations方法,解析方法的注解 和 参数的注解以及对应的值(注意这个值不是参数值)。

5.在HttpServiceMethod的parseAnnotations方法中,将解析生成的RequestFactory,生成请求适配器CallAdapter和响应转换器Converter,然后将三者封装到HttpServiceMethod的子类并返回。通过createCallAdapter方法,遍历Retrofit的CallAdapter列表,寻找是否有符合处理该adapterType的CallAdapter,需要传入返回的适配器类型、注解内容、Retrofit对象。(CallAdapter<?, ?> adapter = callAdapterFactories.get(i).get(returnType, annotations, this))。通过createResponseConverter方法,遍历Retrofit的转换器列表,寻找合适的转换器。需要传入的参数是返回的参数值类型、注解内容、Retrofit对象(Converter<ResponseBody, ?> converter = converterFactories.get(i).responseBodyConverter(type, annotations, this);)

6.将解析生成的RequestFactory,生成请求适配器CallAdapter和响应转换器Converter,还有okhttp3.Call.Factory, 这个四个实例封装到CallAdapted实例中,并返回CallAdapted实例。

7.调用CallAdapted的invoke方法,invoke函数主要是构建OkHttpCall并调用adapt函数。本质是调用ResponseCallAdapter的adapt函数。这个adapter是CallAdapter.Factory类型。返回Call对象。

 

4.3接口类方法注解解析流程

1.通过RequestFactory.parseAnnotations方法,解析方法的注解 和 参数的注解以及 值。

2.在构建RequestFactory.Builder的构造方法中会:(1)获取方法的所有的注解。(2)获取方法参数的所有类型。(3)获取方法参数上的所有的注解。

3.通过parseMethodAnnotation解析方法上的注解。(本质是解析注解中的值,比如1.通过?解析参数;2.解析URI中的参数)

4.返回RequestFactory对象。

 

 

4.4callAdapter解析流程:

1.调用retrofit.callAdapter(returnType, annotations),根据返回类型retrunType选择合适的请求适配器。从头开始遍历,如果前面适配器符合条件,意味着会被优先选用。

2.首先判断是否是CompletableFutureCallAdapterFactory,根据getRawType(returnType) != CompletableFuture.class是否成立,不成立,返回null,成立则返回CompletableFutureCallAdapterFactory创建的适配器。

3.然后判断是否是DefaultCallAdapterFactory,根据getRawType(returnType) != Call.class是否成立,不成立,返回null。成立则返回DefaultCallAdapterFactory创建的适配器。

 

4.5createResponseConverter创建流程

1.响应转换器与请求适配器的创建过程很相似。在创建Retrofit对象时,会将相关转化器保存到converterFactories列表,通过转化器的responseBodyConverter函数判断是否处理该响应数据。

2.首先判断是否是BuiltInConverters,根据的条件是:type == ResponseBody.class或者type == Void.class或者type == Unit.class),不满足则返回null;

3.然后判断是否是GsonResponseBodyConverter,一般到这里是直接返回GsonResponseBodyConverter。

 

4.6 网络请求流程

1.调用了OkHttpCall的enqueue函数,创建OkHttp的ReallCall对象,并调用enqueue函数。然后发起网络请求,请求成功之后调用parseResponse解析响应数据。

2.调用Retrofit的Callback的onResponse,回调MainThreadExecutor的execute方法,在主线再次执行Retrofit的Callback 的onResponse方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值