只是对网络请求做了一个封装,但是不做具体的网络请求,网络请求由okHttp做的。
讲解版本:
implementation 'com.squareup.retrofit2:retrofit:2.3.0'
implementation 'com.squareup.retrofit2:converter-gson:2.3.0'
简单使用
interface IFreeService {
@GET("api/personalMessage/get/{id}")
fun updatePersonalMessage(
@Path("id") personalId: String
): Call<ResponseBody>
}
var retrofit = Retrofit.Builder().baseUrl("")
//设置数据解析器,创建含有Gson对象实例的GsonConverterFactory
.addConverterFactory(GsonConverterFactory.create())
.build()
// 将接口转换为实现类
var service = retrofit.create(IFreeService::class.java)
var respo = service.updatePersonalMessage("1")
// 同步请求
val request = respo.request()
// 异步请求
respo.enqueue(object : Callback<ResponseBody>{
override fun onFailure(call: Call<ResponseBody>, t: Throwable) {
TODO("Not yet implemented")
}
override fun onResponse(call: Call<ResponseBody>, response: Response<ResponseBody>) {
TODO("Not yet implemented")
}
})
整体流程
- Build设计模式初始化Retrofit对象。根据不同平台初始化不同平台的对应继承子类。生成一个回调回UI线程的执行器,可以将执行结果返回至Ui线程内。生成一个网络请求适配器工厂。
- 通过retrofit.create这个方法生成接口实现类,采用动态代理设计模式,把IFreeService的方法调用集中到了InvocationHandler.invoke,再构建了ServiceMethod,OKHttpCall,返回callAdapter.adapt的结果。使用Converter转化响应数据。
- 借助Retrofit通过okHttp进行网络请求。通过toRequest方法,将retrofit的Request转换成okHttp的Request。对okHttp请求回来的数据通过Converter进行解析,调用到ServiceMethod#toResponse方法,将okhttp3.Response转化为retrofit2.Response。
核心
CallAdapter
callAdapter是由addCallAdapterFactory方法传入的,不传默认DefaultCallAdapterFactory。
DefaultCallAdapterFactory的adapter方法默认返回call。
作用是将包装对象转化为用户自定义对象。
Converter
Converter是由addConverterFactory方法传入的。
作用是将okhttp3.Response转化为retrofit2.Response。
Retrofit#create
public <T> T create(final Class<T> service) {
...
return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
new InvocationHandler() {
private final Platform platform = Platform.get();
@Override public Object invoke(Object proxy, Method method, @Nullable Object[] args)
throws Throwable {
...
// 创建ServiceMethod对象,ServiceMethod主要负责解析它对应的method的各种参数,调用toRequest为OkHttp提供Request。
ServiceMethod<Object, Object> serviceMethod =
(ServiceMethod<Object, Object>) loadServiceMethod(method);
// OkHttpCall内部封装okhttp3.Call。
OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
// 将包装对象转化为用户自定义对象
return serviceMethod.callAdapter.adapt(okHttpCall);
}
});
}
请求数据解析
ServiceMethod#Build()
Builder(Retrofit retrofit, Method method) {
this.retrofit = retrofit;
// 接口方法
this.method = method;
// 接口方法的注解,一般是请求方式
this.methodAnnotations = method.getAnnotations();
// 参数类型
this.parameterTypes = method.getGenericParameterTypes();
// 参数注解数组
this.parameterAnnotationsArray = method.getParameterAnnotations();
}
ServiceMethod#build()
public ServiceMethod build() {
callAdapter = createCallAdapter();
responseType = callAdapter.responseType();
...
responseConverter = createResponseConverter();
for (Annotation annotation : methodAnnotations) {
parseMethodAnnotation(annotation);
}
...
int parameterCount = parameterAnnotationsArray.length;
parameterHandlers = new ParameterHandler<?>[parameterCount];
for (int p = 0; p < parameterCount; p++) {
Type parameterType = parameterTypes[p];
...
Annotation[] parameterAnnotations = parameterAnnotationsArray[p];
...
parameterHandlers[p] = parseParameter(p, parameterType, parameterAnnotations);
}
...
return new ServiceMethod<>(this);
}
接口注解解析
parseHttpMethodAndPath
private void parseHttpMethodAndPath(String httpMethod, String value, boolean hasBody) {
this.httpMethod = httpMethod;
this.hasBody = hasBody;
int question = value.indexOf('?');
if (question != -1 && question < value.length() - 1) {
String queryParams = value.substring(question + 1);
Matcher queryParamMatcher = PARAM_URL_REGEX.matcher(queryParams);
}
// 省略域名的URL
this.relativeUrl = value;
this.relativeUrlParamNames = parsePathParameters(value);
}
参数类型,注解解析
int parameterCount = parameterAnnotationsArray.length;
parameterHandlers = new ParameterHandler<?>[parameterCount];
for (int p = 0; p < parameterCount; p++) {
Type parameterType = parameterTypes[p];
Annotation[] parameterAnnotations = parameterAnnotationsArray[p];
// 把参数类型,参数注解放在一起解析之后存储到了这个ParameterHandler<T>数组中,中间主要做了多种合法性校验,并根据注解的类型,生成不同的 ParameterHandler<T>子类
// ParameterHandler抽象类,在apply方法中进行参数替换
parameterHandlers[p] = parseParameter(p, parameterType, parameterAnnotations);
}
总结
Retrofit和OkHttp合作流程
Retrofit的OkHttpCall内部封装okhttp3.Call,调用enqueue方法时,内部实际调用的是okHttp的enqueue方法,okHttp使用的Request通过ServiceMethod的toRequest方法创建。回调回来的Response,通过parseResponse方法,使用Converter转化为自定义类型的Response。
Retrofit数据处理流程
交给了callAdapter以及converter去处理,callAdapter负责把okHttpCall转成用户自定义对象,converter负责把服务器返回的数据转成具体的实体类。