Retrofit的构建使用了建造者模式,这个模式的优点就是可以构造复杂的对象,方便扩展,并且看起来代码比较简洁,美观;

在开始之前,我们先来看一下Retrofit的成员变量;

这里的变量并不是很多,我们来一个个分析;

**(1)Map<Method, ServiceMethod<?>> serviceMethodCache:**这是一个方法的缓存类,key为网络请求的Method,比如GET,POST等,而ServiceMethod则对应着动态代理解析后的方法类;

**(2)okhttp3.Call.Factory callFactory:**这个是创建OkHttp的工厂类;

**(3)HttpUrl baseUrl:**这个是基础URL,网络请求会带上这个基础URL;

**(4)List<Converter.Factory> converterFactories:**Converter.Factory的集合,Converter.Factory是将返回的数据通过这个工厂转化为对应的数据,比如Gson的GsonConverterFactory工厂类,也就是数据转化器工厂;

**(5)List<CallAdapter.Factory> callAdapterFactories:**CallAdapter.Factory的集合,CallAdapter.Factory是网络请求的适配器工厂,比如把Call转化为RxJava请求的RxJavaCallAdapterFactory工厂,也就是Call转化工厂;

**(6)Executor callbackExecutor:**用于回调网络请求;

**(7)boolean validateEagerly:**用于判断是否需要立即解析方法,这个我们在将动态代理的时候会讲到;

我们看完了Retrofit的成员变量,但是Retrofit的创建是通过Builder来创建的,下面我们来看看Retrofit的Builder的变量有哪些,分别有哪些作用;

4、Retrofit.Builder的创建


4.1、Retrofit.Builder的变量

从图片可以看出,和Retrofit的变量差不多,唯一有区分的就是多了Platform和validateEagerly变量,让我们通过源码来看看这两个是做什么的;

先来看一下这个Platform的赋值;

这个Platform是通过Platform.get()方法获取的,来看看这个方法是啥逻辑;

从图片可以看出,最终是调用的findPlatform()方法;

这个方法会返回Android,Java,Platform等类,主要是用来判断对于的平台,然后获取到对于的Platform;

private static Platform findPlatform() {

try {

Class.forName(“android.os.Build”);

// 判断从系统中获取到的SDK不为0的时候,则为Android平台;

if (Build.VERSION.SDK_INT != 0) {

return new Android();

}

} catch (ClassNotFoundException ignored) {

}

try {

Class.forName(“java.util.Optional”);

// 如果不是Android平台的话,那么就返回Java的平台;

return new Java8();

} catch (ClassNotFoundException ignored) {

}

// 默认的返回值;

return new Platform();

}

而Build.VERSION.SDK_INT的判断逻辑为:

翻译过来的意思就是:

当前在此硬件上运行的软件的SDK版本。这个值在设备启动时不会改变,但可能会在硬件制造商提供OTA更新时改变;

下面我们来看一下这个Android类对应的源码:

Android类对应的源码不多,就几个方法,这里我们重点关注下面这几个方法:

**(1)defaultCallbackExecutor():**默认的线程执行器Executor,从源码可以看出,获取的是主线程的Hander,execute的时候,会post到主线程执行;

**(2)defaultCallAdapterFactories:**获取默认的CallAdapter.Factory,用于创建CallAdapter;

**(3)defaultConverterFactories:**获取默认的数据转换工厂ConverterFactory,用于创建转换器Converter;

总结:Platform主要是用于适配不同的平台,用于获取默认的Executor,请求适配器工厂类CallAdapterFactory,数据转换工厂类ConverterFactory等;

4.2、baseUrl

baseUrl,是我们网络请求的基础URL;

我们进源码里面看一下,具体做了啥操作;

这里主要做了两步操作:

1、首先第一步是通过解析这个baseUrl并返回一个HttpUrl对象; 2、第二步是将第一步创建的HttpUrl对象赋值给Builder;

这里我们主要看第一步的具体操作,这里的逻辑是在HttpUrl的 parse(@Nullable HttpUrl base, String input)里,通过解析URL,判断该请求的scheme是为http还是https,如果不是这其中一个,那么就会抛出异常,源码我们大致看一下;

然后下面还会解析URL,获取到主机地址host,端口号port,具体源码我就不贴了,感兴趣的可以跟着源码看一下;

4.3、Converter.Factory

这个我们上面在接受Retrofit的成员变量的时候有提过,是用于创建Converter的工厂,使用了抽象工厂的设计模式,而Converter是用来将请求返回的数据,转化为对应平台的数据,而这里,我们使用的是Gson平台;

我们先来看一下这个Converter.Factory,看看其背后是怎么实现的;

从源码可以看出,Converter.Factory是Converter的内部类,主要有两个方法,一个是requestBodyConverter,用于将请求的RequestBody转换为对应的转换器Converter;

另一个方法是responseBodyConverter,用于将返回的返回体ResponseBody转换为对应的转换器Converter;

而转换器Converter里面只有一个方法convert,用于将返回的数据转换为对应的类型;

我们在创建Retrofit的实例时,是通过GsonConverterFactory.create()来创建对应的转换器工厂的,下面我们来看看这个Gson的转换器工厂是怎么实现的;

先来看一下这个create()的方法;

最终是走的这里,进行了简单的赋值;

GsonConverterFactory这个工厂最重要的还是responseBodyConverter和requestBodyConverter方法,下面我们来具体分析;

  • requestBodyConverter:

在requestBodyConverter方法里面,通过class的Type类型,创建了Gson的TypeAdapter,这个TypeAdapter很熟悉,就是我们使用gson解析会用到的类,最终通过TypeAdapter和gson的参数创建了GsonRequestBodyConverter对象,下面来瞄一眼这个类的代码;

这个类的源码很简单,我们主要convert()这个方法;

这个方法的逻辑就是将传进来的value值通过TypeAdapter将其转化为ByteString,然后再传进RequestBody作为参数来构建RequestBody对象;

这个方法我们先了解到这里,后面在这个requestBodyConverter调用的地方再来讲一下;

  • responseBodyConverter:

这个方法和上面那个requestBodyConverter方法有点类似,也是通过class的Type类型,创建了Gson的TypeAdapter,最终通过TypeAdapter和gson的参数创建了GsonResponseBodyConverter,同理,我们也来看一下这个类的实现吧;

源码很简单,这里我们也是关注convert()这个方法;

这里的逻辑有没有很熟悉,就是我们经常用的gson解析,通过TypeAdapter读取JsonReader的数据,返回对应的数据类型,这里的参数ResponseBody就是我们上面GsonRequestBodyConverter的convert方法生成的;

到这里GsonConverterFactory就讲的差不多了,后面我们在用到的地方再详细讲一下;

4.5、CallAdapter.Factory

CallAdapter.Factory,从命名可以看出,是用来创建CallAdapter的工厂类,使用了抽象工厂的设计模式,而CallAdapter是用于将Call转化为我们所需要的请求类型,比如将Call转化为RxJava的调用类型;

而CallAdapter里面是通过adapt方法来进行转换的,adapt是接口的一个方法,交给子类去实现,这个方法的逻辑,我们下面将Retrofit的解析时,再统一讲解,这里是需要了解这是一个转换的方法即可;

image.png

下面我们来看看创建CallAdapter的工厂里面都有哪些方法,分别是用来干嘛的;

image.png

这个Factory的逻辑很少,只有几个方法,这里我们主要关注get方法,通过get方法来获取CallAdapter的对象,同理,这里也是交给子类去实现;

而上面我们Retrifit的创建,在CallAdapter.Factory的添加时,使用了RxJava的工厂,也就是RxJava2CallAdapterFactory,用于将Call请求转换为RxJava对应的请求;

下面我们来看看这个RxJava2CallAdapterFactory的实现逻辑吧;

RxJava2CallAdapterFactory的创建,也是通过RxJava2CallAdapterFactory.create()的方法,那么我们来看下这个create方法做了啥?

只是简单的new了一个RxJava2CallAdapterFactory,而构造方法里也没有其他的逻辑了,只是对Scheduler进行赋值,而这里创建时,传的是null;

上面我们看完RxJava2CallAdapterFactory的创建后,下面我们来看一下RxJava2CallAdapterFactory是怎么通过get方法创建一个CallAdapter的;

public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {

Class<?> rawType = getRawType(returnType);

if (rawType == Completable.class) {

// 创建RxJava2CallAdapter

return new RxJava2CallAdapter(Void.class, scheduler, isAsync, false, true, false, false,

false, true);

}

// 创建RxJava2CallAdapter

return new RxJava2CallAdapter(responseType, scheduler, isAsync, isResult, isBody, isFlowable,

isSingle, isMaybe, false);

}

这个方法职责很明确,就是根据各种参数来创建RxJava的CallAdpter,也就是RxJava2CallAdapter;

这里我们来重点关注一个RxJava2CallAdapte的adapt方法的逻辑;

public Object adapt(Call call) {

// 第一步:根据是否是异步的参数创建对应的Observable

Observable<Response> responseObservable = isAsync

? new CallEnqueueObservable<>(call)
new CallExecuteObservable<>(call);

Observable<?> observable;

// 第二步:根据各种判断,再封装一层Observable返回

if (isResult) {

observable = new ResultObservable<>(responseObservable);

} else if (isBody) {

observable = new BodyObservable<>(responseObservable);

} else {

observable = responseObservable;

}

return observable;

}

这个方法的逻辑并复杂,主要是将Call请求转化为RxJava的请求,最终返回一个RxJava的被观察者:Observable,用于进行RxJava类型的网络请求,如上面的示例;

这个方法的逻辑主要有两步,我们先来看一下第一步创建的被观察者,这里会先判断是否是异步,如果是异步的话,那么就创建CallEnqueueObservable,否则就创建CallExecuteObservable;

这两个的区别就是,在调用订阅(subscribe)的时候,会执行CallEnqueueObservable的subscribeActual方法,最终是通过OkHttpCall的enqueue方法来执行异步请求;

而CallExecuteObservable在调用订阅(subscribe)的时候,也会执行CallEnqueueObservable的subscribeActual方法,在这个方法里,就直接调用OkHttpCall的execute方法来执行同步请求;

而第二步的封装,这里我们主要以BodyObservable来进行讲解,这个类会对订阅的观察者进行封装,在onNext方法中将body返回;这一步可以理解为对返回的结果进行处理;

这里是RxJava的用法,我默认你是会的,如果对RxJava还不熟悉的同学,可以后面去看看RxJava的用法;

到此,Retrofit的CallAdapter.Factory的逻辑就先告一段落了,下面我们来看看Retrofit的最终build()方法的逻辑;

4.5、Retrofit.Builder#build

废话不多说,我们直接撸源码;

public Retrofit build() {

// 判断当callFactory(OkHttpClient)为空,就重新创建一个OkHttpClient进行赋值;

okhttp3.Call.Factory callFactory = this.callFactory;

if (callFactory == null) {

callFactory = new OkHttpClient();

}

// 判断Executor为空时,就用Platform的默认Executor进行赋值,上面我们讲过,这里面使用的是主线的的Handler;

Executor callbackExecutor = this.callbackExecutor;

if (callbackExecutor == null) {

callbackExecutor = platform.defaultCallbackExecutor();

}

// 通过添加的CallAdapter.Factory来创建一个新的CallAdapter.Factory集合;

List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);

// 添加Platform的默认CallAdapter.Factory,如果我们没有添加CallAdapter.Factory,那么就会使用这个Platform的默认CallAdapter.Factory; callAdapterFactories.addAll(platform.defaultCallAdapterFactories(callbackExecutor));

// 创建Converter.Factory的集合

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.

// 添加默认的Converter.Factory

converterFactories.add(new BuiltInConverters());

// 添加自定的Converter.Factory

converterFactories.addAll(this.converterFactories);

// 添加Platform的默认Converter.Factory

converterFactories.addAll(platform.defaultConverterFactories());

// 最终创建Retrofit实例;

return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories),

unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);

}

这个build()方法,主要是做各种参数的赋值,最终通过参数来创建Retrofit的实例,那么到这里Retrofit的创建就差不多将完了,下面我们将会学习到Retrofit的核心;

为什么我们可以通过接口定义一个类型,就可以执行请求了,对于这些方法的解析,以及参数的赋值的操作是在哪里呢?

这么就涉及到Retrofit使用的一个很重要的设计模式了,也就是动态代理设计模式;

5、Retrofit的核心,动态代理


5.1、什么是代理?

举个例子,假如我要去超市买水果,可是我好懒,周末就想呆在家里不想出门,但是心里又很想吃水果,那怎么办呢?

只能打开外卖App,在上面买完之后,由外卖小哥送过来,这时候,我就通过中介,外卖App来买到水果,而这个过程叫做代理;

不直接操作,而是委托第三方来进行操作,从而达到目的;

而Java的代理分为静态代理和动态代理;

5.2、什么是静态代理?

如果代理类在程序运行之前就已经存在了,那么这种代理方式就被称为静态代理;

还是以上面的例子,我要买水果,来定义一个买水果的接口Operator;

public interface Operator {

// 买水果

void buyFruit();

}

而我们的代理类外卖App需要实现这个接口,同时,将需要委托的对象传进来,在buyFruit的过程中,做了一些出来,比如去超市取货,取完货之后,再送货;

public class AppAgent implements Operator {

private Operator operator;

public AppAgent(Operator operator) {

this.operator = operator;

}

@Override

public void buyFruit() {

// 1、在App上,提供商品给用户下单

// 2、根据订单去超市采购水果

operator.buyFruit();

// 3、送货给客户

}

}

委托的对象,超市:

public class Market implements Operator {

@Override

public void buyFruit() {

// 到超市买水果

}

}

那么最终的实现效果就是,我们通过外卖App的一顿操作,从超市买到了水果,如下:

public class Main {

public static void main(String[] args) {

// 委托对象,超市;

Market market = new Market();

// 代理对象,外卖App;

AppAgent appAgent = new AppAgent(market);

// 通过外卖App的代理,从超市买到了水果;

appAgent.buyFruit();

}

}

以上就是我们静态代理的过程,这个例子只是举了买水果这个过程,但是如果我还想要买菜,买生活用品等一系列东西呢?

我就得在接口Operator里面再多新增好几个方法,同样的代理类也要跟着去重写一堆的方法,但是这些方法做的操作其实都是一样的,都是买这个动作,但是我们不得已,新增一种类型,我们就得在代理类里面再重写并调用;

那么这个过程其实是可以抽出来的,这种方式就叫做动态代理;

5.3、动态代理

动态代理,和静态代理不同的是,动态代理的方法是运行后才创建的,而静态代理是运行前就存在的了;

说白了,和静态代理不同的是,动态代理的方法都是在运行后,自动生成的,所以叫动态代理;

下面我们来看看动态代理是咋用的;

在使用动态代理的时候,被代理类需要实现InvocationHandler这个接口,,这个invoke方法是在动态生成的代理类中调用的,对应着我们上面在静态代理operator.buyFruit()这个方法的调用,下面来看一下这个方法对应的参数;

public interface InvocationHandler {

// Object proxy:接口的具体实现类;

// Method method:解析之后自动生成的方法;

// Object[] args:方法对于的参数;

Object invoke(Object proxy, Method method, Object[] args);

}

而最终运行时生成的代理类,一般名称会是Proxy1这种,通过Proxy.newProxyInstance()方法来生成的,这个下面会讲到,先来看一下下面的伪代码;

public final class $Proxy0 extends Proxy implements Operator {

public final boolean buyFruit() {

// h是InvocationHandlel,调用了invoke方法;

super.h.invoke(this, m1, (Object[])null);

}

}

}

在生成的代理类中,会实现我们的接口,并重写方法,在方法里面通过InvocationHandler回调参数到invoke方法里,最终通过反射调用被代理对象的方法;

而我们通过实现这个InvocationHandler接口,在invoke方法里面,通过method.invoke(object, args)可以来调用被代理的方法,然后我们可以在这个method.invoke(object, args)之前或者之后做一些处理,这样所以的方法都可以一并进行处理,而不是每次新增一个方法,就得重写一遍逻辑;

下面来看一下具体实现:

public class CustomProxy implements InvocationHandler {

private Object object;

public CustomProxy(Object object) {

this.object = object;

}

@Override

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

// 1、在App上,提供商品给用户下单

// doSomeThing();

// 2、根据订单去超市采购东西(在这个方法之前或者之后都可以统一处理操作)

Object invoke = method.invoke(object, args);

// 3、送货给客户

// doSomeThing();

return invoke;

}

}

下面来看一下,最终的调用;

public class Main {

public static void main(String[] args) {

// 创建被代理类

CustomProxy customProxy = new CustomProxy(new Market());

// 动态生成代理类

Operator proxyInstance = (Operator) Proxy.newProxyInstance(Operator.class.getClassLoader(), new Class[]{Operator.class}, customProxy);

// 调用对应的方法

proxyInstance.buyFruit();

}

}

这里通过Proxy.newProxyInstance()方法,动态生成代理类$Proxy0这种,这里涉及到的反射的知识,就不再赘述了;

然后动态代理类调用方法,最终会走到CustomProxy的invoke()方法,然后我们在这个方法里面通过method.invoke(object, args)来进行最终的代理调用,而在这个最终的代理调用的前后,我们可以实现自定义的逻辑;

这个实现了InvocationHandler接口的CustomProxy,更像是一个拦截类,在代理方法的调用过程中进行拦截,然后再实现我们的自定义逻辑;

至此,动态代理你理解了吗?没有理解也没关系,多看几遍,多练几遍就可以了;

6、Retrofit的动态代理


6.1、Retrofit为什么要使用动态代理?

首先,让我们来想一个问题,Retrofit为什么要使用动态代理?

使用动态代理的好处就是在调用方法之前,我们可以统一做一些操作,而不必新增一个方法就去写一遍逻辑;

而Retrofit巧妙的使用了动态代理在调用接口的方法之前,统一的去解析处理Header和URL等操作;

这样就不用每次在新增一个请求的方法,就去写一遍这个解析的逻辑;

那么接下来我们来看看Retrofit的怎么解析这些接口的;

6.2、Retrofit是怎么使用动态代理的?

下面我们来看一下Retrofit的create的方法,动态代理的逻辑是在这里实现的;

public T create(final Class service) {

// 验证接口的参数以及配置是否正确

if (validateEagerly) {

eagerlyValidateMethods(service);

}

// 动态代理

return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },

new InvocationHandler() {

private final Platform platform = Platform.get();

private final Object[] emptyArgs = new Object[0];

@Override public Object invoke(Object proxy, Method method, @Nullable Object[] args)

throws Throwable {

// 判断是否是Object,如果是的话,就直接调用方法返回

if (method.getDeclaringClass() == Object.class) {

return method.invoke(this, args);

}

// 判断是否是Java8平台的默认方法类型,如果是的话,就调用Java8平台的invokeDefaultMethod方法

if (platform.isDefaultMethod(method)) {

return platform.invokeDefaultMethod(method, service, proxy, args);

}

// 解析方法;

return loadServiceMethod(method).invoke(args != null ? args : emptyArgs);

}

});

}

这里我们将这个方法分为两步;

第一步: eagerlyValidateMethods方法,这个方法的逻辑是用于加载接口的配置,用于判断接口对应的header,body以及方法的参数等配置是否正确,如果不正确那么就会抛出异常;

第二步: loadServiceMethod方法,这个方法的逻辑主要是用于解析我们在接口配置的注解以及参数,比如header,body,url等等;

这里我们重点关注第二步的loadServiceMethod方法方法;

我们来看一下其源码的具体实现;

ServiceMethod<?> loadServiceMethod(Method method) {

// 先从缓存map集合里面获取ServiceMethod;

ServiceMethod<?> result = serviceMethodCache.get(method);

if (result != null) return result;

synchronized (serviceMethodCache) {

result = serviceMethodCache.get(method);

if (result == null) {

// 如果从缓存map里面获取不到ServiceMethod,那么再通过解析注解,获取到ServiceMethod对象;

result = ServiceMethod.parseAnnotations(this, method);

// 将解析后的ServiceMethod对象存入到map集合中;

serviceMethodCache.put(method, result);

}

}

return result;

}

这里做的操作很简单,就是获取ServiceMethod,而在获取ServiceMethod的过程中,会先从缓存的map中获取,如果获取不到了再进行解析,这样就不必获取一次ServiceMethod,就去解析一次,比较耗性能;

而这个ServiceMethod的类是个抽象类,只有两个方法,一个是静态的parseAnnotations方法,一个是抽象的invoke方法;

我们先来看一下这个parseAnnotations方法;

static ServiceMethod parseAnnotations(Retrofit retrofit, Method method) {

// 通过解析接口方法的注解,获取RequestFactory

RequestFactory requestFactory = RequestFactory.parseAnnotations(retrofit, method);

// 解析注解并获取ServiceMethod对象

return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);

}

这个方法的逻辑也不是很复杂,主要分为两步;

第一步: 获取RequestFactory;

第二步: 获取ServiceMethod;

我们先来看第一步的操作;

static RequestFactory parseAnnotations(Retrofit retrofit, Method method) {

return new Builder(retrofit, method).build();

}

通过Builder来创建RequestFactory,来看看这个Builder做了啥操作;

Builder(Retrofit retrofit, Method method) {

this.retrofit = retrofit;

this.method = method;

// 获取方法所有的注解,包括自己声明的以及继承的

this.methodAnnotations = method.getAnnotations();

// 获取方法参数的所有类型,包含泛型;

this.parameterTypes = method.getGenericParameterTypes();

// 获取方法参数上的所有注解

this.parameterAnnotationsArray = method.getParameterAnnotations();

}

这个方法的逻辑很简单,就是做一些赋值操作,这里需要注意的是这几个反射的方法,下面的build方法会用到;

RequestFactory build() {

for (Annotation annotation : methodAnnotations) {

// 遍历方法的注解,解析方法的参数配置,获取到请求的url,header等参数

parseMethodAnnotation(annotation);

}

int parameterCount = parameterAnnotationsArray.length;

parameterHandlers = new ParameterHandler<?>[parameterCount];

for (int p = 0; p < parameterCount; p++) {

// 遍历方法的参数,以及参数的类型,解析方法的参数逻辑

parameterHandlers[p] = parseParameter(p, parameterTypes[p], parameterAnnotationsArray[p]);

}

// 根据上面解析的参数配置,创建RequestFactory

return new RequestFactory(this);

}

这个方法的逻辑就比较重要了,我们在接口的方法里面定义的相关url,header等注解,最终就是在这里解析并转化为okhttp请求的Call,那么我们来看看这里到底是怎么解析的;

先来看一下parseMe

《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》

开源分享完整内容戳这里

thodAnnotation这个方法, 这个方法的主要逻辑是用于解析方法注解的配置信息;

下面我们来看看这个类的具体实现;

这个方法的逻辑比较多,我们大致看一下就可以了,这里面做的主要职责就是通过注解Annotation,获取到url,header,isMultipart等参数,并将其赋值给建造者Builder的成员变量;

对于这个方法,这里就不多说了,感兴趣的跟着源码去看一下;

而第二个方法parseParameter,也是遍历上面获取到的方法的参数类型parameterTypes以及方法参数的注解parameterAnnotationsArray,来解析并获取相关配置,而这个方法最终是调的parseParameterAnnotation方法的逻辑;

主要是用于解析这里的逻辑:

下面我们来看看具体实现;

这个parseParameterAnnotation方法的逻辑和上面的parseMethodAnnotation方法有点类似,也是通过判断对于的类型来进行解析,这里源码过长,就不贴出来了;

这里我们就找其中一个Query的解析来进行分析;

省略前面的代码

else if (annotation instanceof Query) {

// 将注解annotation强转为Query

Query query = (Query) annotation;

// 获取注解Query对应的值;

String name = query.value();

if (Iterable.class.isAssignableFrom(rawParameterType)) {

// 判断这个参数的类型为Class类型;

// 创建ParameterHandler的子类Query

return new ParameterHandler.Query<>(name, converter, encoded).iterable();

}

}

省略后面的代码

这里最终解析获取的是ParameterHandler.Query类,这个类里面有个apply的方法,会在接口请求的时候会调用到,目的是通过请求的RequestBuilder将解析出来的参数,添加到RequestBuilder里去;

这里我们了解一下就可以了;

这里还有一个需要注意的点,就是这里的解析,涉及到Converter这个convert方法的逻辑;

这里我以Body为例,在Body这个类的apply方法里,会通过Converter这个convert方法,将body参数转化为对应类型的数据;

这个apply的方法是在进行网络请求的时候会调用,具体调用链如下,这里以RxJava为例:

1、RxJavaCallAdapterFactory.ResponseCallAdapter的adapt方法;

2、RxJavaCallAdapterFactory.CallOnSubscribe的call方法;

Android 网络框架之Retrofit源码解析,flutter边框特效相关推荐

  1. Android 网络编程之OkHttp源码解析

    前言:OkHttp框架是Android的网络请求框架,无数的项目都在使用着这个框架,重要性不言而喻; 本文会将OKHTTP的源码进行拆解,每个部分来单独学习,由简入深,循序渐进,篇幅较长,建议收藏,慢 ...

  2. android网络重试机制,okhttp源码解析(四):重试机制

    前言 这一篇我们分析okhttp的重试机制,一般如果网络请求失败,我们会考虑连续请求多次,增大网络请求成功的概率,那么okhttp是怎么实现这个功能的呢? 正文 首先还是回到之前的Intercepto ...

  3. Retrofit源码解析

    本文分析的源码基于retrofit:2.9.0. 前言 Retrofit基于OkHttp,网络请求的工作本质上是 OkHttp 完成,而 Retrofit 仅负责 网络请求接口的封装,它们的关系示意图 ...

  4. Retrofit 源码解析(2.9.0 版本)

    文章目录 1.简介 2.Retrofit 配置与基本用法 2.1 依赖引入与配置 2.2 基本用法 3.Retrofit 的注解 3.1 请求方法注解 3.2 请求头注解 3.3 请求参数注解 3.4 ...

  5. Android多线程之ArrayBlockingQueue源码解析

    阻塞队列系列 Android多线程之LinkedBlockingQueue源码解析 Android多线程之SynchronousQueue源码解析 Andorid多线程之DelayQueue源码分析 ...

  6. Android多线程之IntentService源码解析

    想要了解 IntentService 的工作原理需要先对 Android 系统中以 Handler.Looper.MessageQueue 组成的异步消息处理机制以及 HandlerThread 有所 ...

  7. Android Glide 3.7.0 源码解析(八) , RecyclableBufferedInputStream 的 mark/reset 实现

    个人博客传送门 一.mark / reset 的作用 Android Glide 3.7.0 源码解析(七) , 细说图形变换和解码有提到过RecyclableBufferedInputStream ...

  8. 轻量级Rpc框架设计--motan源码解析六:client端服务发现

    一, Client端初始化工作 client端通过RefererConfigBean类实现InitializingBean接口的afterPropertiesSet方法, 进行下面三项检查配置工作: ...

  9. android网络框架retrofit源码解析二

    注:源码解析文章参考了该博客:http://www.2cto.com/kf/201405/305248.html 前一篇文章讲解了retrofit的annotation,既然定义了,那么就应该有解析的 ...

最新文章

  1. 数据蒋堂 | JOIN提速 - 外键指针的衍生
  2. 算法设计7—哈希表1
  3. symfony2 环境搭建笔记
  4. Java面向对象之构造方法
  5. 单元测试之更强大的powermock
  6. html5 字符相等,js里返回字符ok与字符ok比较不相等的问题
  7. 计算机网络ieee,博士生程珂论文连续两年被计算机网络顶级会议IEEE INFOCOM录用...
  8. LeetCode 1011. 在 D 天内送达包裹的能力(二分查找)
  9. AWS拓展中国合作伙伴生态 加速企业数字化转型进程
  10. LeetCode —— 145. 二叉树的后序遍历【递归与迭代】(Python)
  11. 七牛解决运营商劫持问题
  12. 精通开关电源设计第二版pdf_11、秋招年35月准备期——Verilog HDL高级数字设计(第二版)...
  13. SAP License:关于MRP产生的采购申请检查、与采购部的衔接处理
  14. /usr/lib/x86_64-linux-gnu/libQt5Core.so.5: version `Qt_5.12‘ not found解决办法
  15. 简单计算经纬度表示的距离
  16. android长度测量工具,手机测量尺子工具
  17. STC4054锂电池充电IC
  18. 安卓手机使用VNET抓包京东wskey
  19. ios 强制横屏大总结
  20. 【MFC】多国语言工具栏

热门文章

  1. 开发中常见的一些插件收藏
  2. Simulink 环境基础知识(二十六)--信号基础知识
  3. 移动端网页开发-vh/vw/rem
  4. nas文件服务器改造,nas 文件服务器的配置
  5. 自学单片机难吗?单片机编程教学怎么选?
  6. LTE信令流程——附着
  7. Core Techniques And Algorithms In Game Programming
  8. Python DistributedDataParallel(DDP)训练模型
  9. Python爬虫入门教程 65-100 爬虫与反爬虫的修罗场,点评网站,字体反爬之三
  10. 数据库安全性 --- 概述