Retrofit 整理
Posted 且听真言
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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方法。
以上是关于Retrofit 整理的主要内容,如果未能解决你的问题,请参考以下文章
Retrofit VS OkHttp,谁是最强网络开发框架?
开发 Material Design+RxJava+Retrofit+MVP App 参考资料