1. 介绍
Retrofit主要是基于OKHttp进一步封装的网络请求的框架。它采用了一种接口方法声明请求的方式,使用方法注解和方法参数注解进行标记请求信息,通过动态代理访问接口方法并解析Method,最后将请求信息汇总组装成okhttp3.Request对象,再根据接口方法返回值类型决定调用适配器(CallAdapter),内部通过okhttp3.Call.enqueue(…) 或okhttp3.Call.execute() 同步/异步请求,请求响应后通过转换器(Converter)把okhttp3.ResponseBody数据再进行一次转换得到最后的数据。
2.用法
这一小节通过一系列不同请求方式的代码来展示相关的用法。
主要分为6个文件,具体代码文件在最后面。
- ServiceInterface.kt 声明接口请求
- Main.kt 测试接口请求
- ApiConverterFactory.java 转换器工厂类
- ApiRequestBodyConverter.java 转为RequestBody对象转换器类 (@Part 参数对象转为RequestBody)
- ApiResponseBodyConverter.java ResponseBody对象转换器类
- HttpBinResponse.java ResponseBody装好后的数据类
2.1 基本用法
- 1.GET 请求下载文件
- 2.GET 请求
- 3.GET 请求 查询?name=value
- 4.GET 请求 查询?name
- 5.POST 请求
- 6.POST 请求 表单数据提交 name=“名字”&content=“内容”
- 7.POST 请求 多部分表单提交 multipart/form-data
2.2 其他用法
-
- 通过@URL 请求一个不同地址的URL
-
- 通过Interceptor拦截器,实现动态设置不同BaseUrl
3. 源码
这一小节,通过一个post表单提交梳理下执行流程。以下是这个post请求的代码:分为三部分
-
- 接口请求声明部分
-
- Retrofit类构建,并返回接口的实现类部分
-
- 接口请求测试部分
interface ServiceInterface {
...
companion object {
var BASE_URL = "http://www.httpbin.org/"
}
@POST("/post")
@FormUrlEncoded
fun post(@Field("name") name:String,@Field("content") content:String): Call<ResponseBody>
...
}
public class Main {
...
private static ServiceInterface sServiceInterface
= new Retrofit.Builder()
.baseUrl(ServiceInterface.Companion.getBASE_URL())
.client(new OkHttpClient.Builder().build())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.addConverterFactory(ApiConverterFactory.create())
.build()
.create(ServiceInterface.class);
/**
* Post请求,表单提交 @FormUrlEncoded @Field
*/
@Test
public void testPostFormUrlEncoded(){
String s = null;
try {
Response<ResponseBody> response = sServiceInterface.post("名字","内容").execute();
s = response.body().string();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(s);
}
...
}
从sServiceInterface.post("名字","内容").execute();
开始分析
1.先看看sServiceInterface
是怎么创建的?
2.再看看调用post("名字","内容")
方法是怎么回事?
3.最后看下执行execute()
是怎么样的?
开始分析1.
//先进入Retrofit#create(..)方法
public <T> T create(final Class<T> service) {
return (T)
Proxy.newProxyInstance(
service.getClassLoader(),
new Class<?>[] {
service},
new InvocationHandler() {
...
@Override
public @Nullable Object invoke(Object proxy, Method method, @Nullable Object[] args)
throws Throwable {
...
return platform.isDefaultMethod(method)
? platform.invokeDefaultMethod(method, service, proxy, args)
: loadServiceMethod(method).invoke(args); //看重点部分
}
});
//分析1结束,通过Proxy.newProxyInstance(..)动态代理获取接口ServiceInterface代理对象。
开始分析2.
从上一步的loadServiceMethod(method).invoke(args)
开始分为2个部分:
- 2.1
loadServiceMethod(method)
- 2.2 调用
invoke(args)
方法
开始分析2.1 loadServiceMethod(method)
//从Retrofit#loadServiceMethod(..)开始
ServiceMethod<?> loadServiceMethod(Method method) {
...
result = ServiceMethod.parseAnnotations(this, method);
...
}
return result;
}
//ServiceMethod#parseAnnotations(..)
static <T> ServiceMethod<T> parseAnnotations(Retrofit retrofit, Method method) {
//解析生成RequestFactory对象,具体流程在【流程图】图片有描述
RequestFactory requestFactory = RequestFactory.parseAnnotations(retrofit, method);
return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
}
//HttpServiceMethod.parseAnnotations(..)
static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations(
Retrofit retrofit, Method method, RequestFactory requestFactory) {
...
adapterType = method.getGenericReturnType();
...
//获取调用适配器CallAdapter对象,具体流程在【流程图】图片有描述
CallAdapter<ResponseT, ReturnT> callAdapter =
createCallAdapter(retrofit, method, adapterType, annotations);
Type responseType = callAdapter.responseType();
...
//获取转换器Converter对象,具体流程在【流程图】图片有描述
Converter<ResponseBody, ResponseT> responseConverter =
createResponseConverter(retrofit, method, responseType)