what
网络请求框架,底层是使用OkHttp请求实现的。通过动态代理来创键创键解耦的请求,具体的请求交给OkHttp。同时支持Rxjava,以及各种格式的转换。官方文档地址:Retrofit
how
定义请求API
创键接口,以及请求定义方法
1 | import okhttp3.ResponseBody; |
请求
1 | Retrofit retrofit = new Retrofit.Builder().baseUrl(url).build(); |
请求方法声明
@GET
get请求
1 | "article/list/0/json") ( |
@POST
1 | "login") ( |
其它的请求方式
PUT
, DELETE
, and HEAD
Url构建
@Path
当我们需要对路径进行动态参数,比如`/page/1/json,这种带参路径,好像和springMVC的挺像,这样就会替换了
如果路径种出现了多个参数,映射形参一定要按照顺序写,不然会出问题
1 | "article/list/{pageNum}/json") ( |
@Query
url查询参数
1 | "article/list/0/json") ( |
@Path和@Query共同出现时,映射形参一定要先path再query的写,不然真的会出问题呃呃
@QueryMap
这个和@Query类似,传入map表示查询参数
1 | "group/{id}/users") ( |
请求体构建
@Field和@FormUrlEncoded
post提交表单得这样
1 | "user/login") ( |
@Body
标注请求体
自定义RequestBody,参看OkHttp,这里不需要FormUrlEncoded
1 | "xxxxxxx") ( |
如果没有加入转化器的话就只能修饰RequestBody
请求体为json对象
1 | "xxxxxxx") ( |
@Multipart 和 @Part
其实也是完全对应OkHttp的
1 |
|
请求头构建
@Headers 和 @Headers @HeaderMap
添加单个Header头
1 | "Cache-Control: max-age=640000") ( |
添加多个
1 | ({ |
动态赋值Header
1 | "user") ( |
动态添加多个
1 | "user") ( |
基本上一一对应着OkHttp,真好用啊
转换器
默认Retrofit是响应构建是发出RequestBody
和响应ResponseBody
,如果需要进一步对响应进行转换处理就需要用到转换器了。
大概有这么几种把:(官网拷的)
- Gson:
com.squareup.retrofit2:converter-gson
- Jackson:
com.squareup.retrofit2:converter-jackson
- Moshi:
com.squareup.retrofit2:converter-moshi
- Protobuf:
com.squareup.retrofit2:converter-protobuf
- Wire:
com.squareup.retrofit2:converter-wire
- Simple XML:
com.squareup.retrofit2:converter-simplexml
- Scalars (primitives, boxed, and String):
com.squareup.retrofit2:converter-scalars
Gson
1 | Retrofit retrofit = new Retrofit.Builder() |
call适配器
联动Rxjava
导入依赖
1 | implementation 'com.squareup.retrofit2:converter-gson:2.5.0' |
添加
1 |
|
Gson和Rxajva结合后,接着我们请求API就可以这样写了
定义和响应对应的实体
1 | public class BaseResponse<T> { |
定义API
1 | public interface HomeApis { |
发送请求处理
1 | addRxSubscribe( mModel.getArticles(pageNum) |
顺带着我们可以将线程变换,以及初步的响应处理进行复用,使用Rxjava进行流处理就行,甚至我们可以再重写一个Observer等等(我也是看别人代码这样学的写的哈哈)
1 | public class RxUtil { |
why
这个大概的原理就是通过动态代理取生成api,读取注解,组装request,构建成真正的OkHttp的Call,继而调用。
创键API
1 | Retrofit retrofit = new Retrofit.Builder() |
上面的Builder模式就先不看了,直接从create开始
1 | public <T> T create(final Class<T> service) { |
动态代理返回的对象,实际调用的调用是根据具体的methdo去构建的ServiceMethod.invoke方法。
先看下loadServiceMethod(method)
吧,首先去map查询,没查询到就解析构建
1 | ServiceMethod<?> loadServiceMethod(Method method) { |
接着到ServiceMethod#parseAnnotations
1 | static <T> ServiceMethod<T> parseAnnotations(Retrofit retrofit, Method method) { |
接着走向RequestFactory#parseAnnotations去解析注解
1 | static RequestFactory parseAnnotations(Retrofit retrofit, Method method) { |
直接看build方法
1 | RequestFactory build() { |
调用parseMethodAnnotation
1 | private void parseMethodAnnotation(Annotation annotation) { |
在这里就很明显,根据不同的注解进行解析。反正都是去获得注解的值啊生成,最终在invoke组建真正的call尽调用。
后面都是直接装配之前解析的东西了
最后看看HttpServiceMethod#invoke
1 | ReturnT invoke(Object[] args) { |
这里的话就会去返回OkHttpCall
里面调用产生的原生的OkHttp
的Call
,外面包裹着callAdapter
,这里是用于转换Call的,即又进行了一次适配,不过这次的对象是call,这个为啥要适配呢,默认的话我们返回的是Call<>
这种样子的,但是我们可以给定Adapteri进行对Call进一步处理,比如RxJava适配器
1 | Retrofit provideRetrofit(OkHttpClient client) { |
然后我们就能产生Observale<>
的东西了。
继续看OkHttpCall是个啥东西。它实现了Retrofit的Call,里面包裹着真正的OkHttp的Call。所以形式很明了了。
通过调Retorfit的Call的execute或者enqueue,去组建真正的Call然后调用到OkHttp了。
1 | public Response<T> execute() throws IOException { |
原理呢就大概是这样。适配器和转换器也很明了
Gson相应体转换器
1 | final class GsonResponseBodyConverter<T> implements Converter<ResponseBody, T> { |
RxJava Call适配器
1 | final class RxJava2CallAdapter<R> implements CallAdapter<R, Object> { |