目录
b.讲解二:createResponseConverter()
1.Retrofit.create(接口类)
public <T> T create(final Class<T> service) {
//对传入的字节码验证
Utils.validateServiceInterface(service);
//标志位判断,是否需要提前验证
if (validateEagerly) {
//内部判断平台,获取接口方法,遍历判断等等。
eagerlyValidateMethods(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, Object... args)
throws Throwable {
// If the method is a method from Object then defer to normal invocation.
if (method.getDeclaringClass() == Object.class) {
return method.invoke(this, args);
}
if (platform.isDefaultMethod(method)) {
return platform.invokeDefaultMethod(method, service, proxy, args);
}
ServiceMethod serviceMethod = loadServiceMethod(method);
OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);
return serviceMethod.callAdapter.adapt(okHttpCall);
}
});
}
1)提前验证
Retrofit的成员变量validateEagerly,为true表示提前验证,看看eagerlyValidateMethods():
private void eagerlyValidateMethods(Class<?> service) {
//获取平台 android? ios?
Platform platform = Platform.get();
//遍历service接口类方法
for (Method method : service.getDeclaredMethods()) {
if (!platform.isDefaultMethod(method)) {
loadServiceMethod(method);
}
}
}
看看isDefaultMethod(..):
//默认返回false
boolean isDefaultMethod(Method method) {
return false;
}
当非默认方法,调用loadServiceMethod(..):
public final class Retrofit {
private final Map<Method, ServiceMethod> serviceMethodCache = new LinkedHashMap<>();
ServiceMethod loadServiceMethod(Method method) {
//ServiceMethod即对接口单个方法的封装
ServiceMethod result;
//锁缓存ServiceMethod的map
synchronized (serviceMethodCache) {
//先从缓存拿
result = serviceMethodCache.get(method);
if (result == null) {
//构建模式 创建ServiceMethod -> 放入缓存
result = new ServiceMethod.Builder(this, method).build();
serviceMethodCache.put(method, result);
}
}
//最终返回ServiceMethod
return result;
}
...
}
2)动态代理部分
接下来再回去看看create()后面的操作:
public <T> T create(final Class<T> service) {
...
//重点
//动态代理 传入接口类,当调用接口类方式时,会调用第三参数InvocationHandler的invoke方法
//invoke方法就是核心
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, Object... args)throws Throwable {
//非android平台:方法是Object中的方法(equals等等)
if (method.getDeclaringClass() == Object.class) {
return method.invoke(this, args);
}
//非android平台
if (platform.isDefaultMethod(method)) {
return platform.invokeDefaultMethod(method, service, proxy, args);
}
//核心1:android平台
//ServiceMethod对应retrofit接口类中的一个方法
//loadServiceMethod方法介绍过,判断缓存是否有对应的ServiceMethod
ServiceMethod serviceMethod = loadServiceMethod(method);
//核心2
OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);
//核心3
return serviceMethod.callAdapter.adapt(okHttpCall);
}
});
}
核心1-ServiceMethod:
final class ServiceMethod<T> {
...
final okhttp3.Call.Factory callFactory; //网络请求工厂,生产网络请求
final CallAdapter<?> callAdapter;//网络请求适配器,将call请求适用各平台
private final HttpUrl baseUrl;//基础url
private final Converter<ResponseBody, T> responseConverter;//数据转化器
private final String httpMethod;//请求方法 get post
private final String relativeUrl;//网络请求的相对地址,和基础url拼接成完成地址
private final Headers headers;//请求头
private final MediaType contentType;//请求http报文的body类型
//标志位
private final boolean hasBody;
private final boolean isFormEncoded;
private final boolean isMultipart;
//用途:解析retrofit接口类的方法和方法上注解
private final ParameterHandler<?>[] parameterHandlers;
//构建者模式 实现 初始化
ServiceMethod(Builder<T> builder) {
this.callFactory = builder.retrofit.callFactory();
this.callAdapter = builder.callAdapter;
this.baseUrl = builder.retrofit.baseUrl();
this.responseConverter = builder.responseConverter;
this.httpMethod = builder.httpMethod;
this.relativeUrl = builder.relativeUrl;
this.headers = builder.headers;
this.contentType = builder.contentType;
this.hasBody = builder.hasBody;
this.isFormEncoded = builder.isFormEncoded;
this.isMultipart = builder.isMultipart;
this.parameterHandlers = builder.parameterHandlers;
}
...
static final class Builder<T> {
...
public Builder(Retrofit retrofit, Method method) {
this.retrofit = retrofit;
//请求方法
this.method = method;
//接口方法中的注解 比如@path @get等
this.methodAnnotations = method.getAnnotations();
//获取接口方法里面参数的类型
this.parameterTypes = method.getGenericParameterTypes();
//获取接口方法里面参数的内容
this.parameterAnnotationsArray = method.getParameterAnnotations();
}
public ServiceMethod build() {
//下方讲解(讲解一) 作用: 根据网络请求接口方法的返回值和注解类型,从retrofit获取对应的
//网络接口适配器
callAdapter = createCallAdapter();
//下方讲解 作用:从callAdapter(根据网络请求接口方法的返回值和注解类型)获取网络适配器
//返回的数据类型
responseType = callAdapter.responseType();
...
//创建数据转换器 下方讲解(讲解二)
responseConverter = createResponseConverter();
//遍历网络请求方法注解
for (Annotation annotation : methodAnnotations) {
//解析接口中的方法注解
parseMethodAnnotation(annotation);
}
//必须有请求方式
if (httpMethod == null) {
throw methodError("HTTP method annotation is required (e.g., @GET, @POST, etc.).");
}
if (!hasBody) {
if (isMultipart) {
throw methodError(
"Multipart can only be specified on HTTP methods with request body (e.g., @POST).");
}
if (isFormEncoded) {
throw methodError("FormUrlEncoded can only be specified on HTTP methods with "
+ "request body (e.g., @POST).");
}
}
//获取方法参数的长度
int parameterCount = parameterAnnotationsArray.length;
parameterHandlers = new ParameterHandler<?>[parameterCount];
for (int p = 0; p < parameterCount; p++) {
Type parameterType = parameterTypes[p];
//遍历通过parseParameter解析参数
parameterHandlers[p] = parseParameter(p, parameterType, parameterAnnotations);
}
...
return new ServiceMethod<>(this);
}
}
}
a.讲解一:CallAdapter()
private CallAdapter<?> createCallAdapter() {
//获取接口方法的返回类型
Type returnType = method.getGenericReturnType();
if (Utils.hasUnresolvableType(returnType)) {
...
//获取接口方法里面的注解类型
Annotation[] annotations = method.getAnnotations();
try {
//从retrofit获取对应的网络请求适配器
return retrofit.callAdapter(returnType, annotations);
} catch (RuntimeException e) {
throw methodError(e, "Unable to create call adapter for %s", returnType);
}
}
看看retrofit.callAdapter(returnType, annotations):
public CallAdapter<?> callAdapter(Type returnType, Annotation[] annotations) {
return nextCallAdapter(null, returnType, annotations);
}
public CallAdapter<?> nextCallAdapter(CallAdapter.Factory skipPast, Type returnType,
Annotation[] annotations) {
...
int start = adapterFactories.indexOf(skipPast) + 1;
//遍历CallAdapter工厂集合,寻找合适的工厂
for (int i = start, count = adapterFactories.size(); i < count; i++) {
//合适时候,通过get()创建需要的CallAdapter
CallAdapter<?> adapter = adapterFactories.get(i).get(returnType, annotations, this);
//无合适的抛出异常
if (adapter != null) {
return adapter;
}
}
...
}
b.讲解二:createResponseConverter()
private Converter<ResponseBody, T> createResponseConverter() {
//获取方法的注解类型
Annotation[] annotations = method.getAnnotations();
try {
//返回Converter
return retrofit.responseBodyConverter(responseType, annotations);
} catch (RuntimeException e) { // Wide exception range because factories are user code.
throw methodError(e, "Unable to create converter for %s", responseType);
}
}
进入responseBodyConverter():
public <T> Converter<ResponseBody, T> responseBodyConverter(Type type, Annotation[] annotations) {
return nextResponseBodyConverter(null, type, annotations);
}
public <T> Converter<ResponseBody, T> nextResponseBodyConverter(Converter.Factory skipPast,
Type type, Annotation[] annotations) {
...
//找到合适的数据解析器 默认json,即jsonResponseBodyConverter
int start = converterFactories.indexOf(skipPast) + 1;
for (int i = start, count = converterFactories.size(); i < count; i++) {
Converter<ResponseBody, ?> converter =
converterFactories.get(i).responseBodyConverter(type, annotations, this);
if (converter != null) {
//noinspection unchecked
return (Converter<ResponseBody, T>) converter;
}
}
...
}
c:总结ServiceMethod的build()
封装了请求头,请求方式,请求路径等等,并创建好网络请求适配器、数据转换器,最终通过parameterHandlers遍历解析retrofit接口类的方法和方法上注解。
核心2-OkHttpCall :
OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);
final class OkHttpCall<T> implements Call<T> {
//请求参数等等信息
private final ServiceMethod<T> serviceMethod;
//接口参数
private final Object[] args;
//是否取消请求
private volatile boolean canceled;
//调用的原生OKhttp的call
private okhttp3.Call rawCall;
//异常
private Throwable creationFailure;
//请求已执行的标志
private boolean executed;
OkHttpCall(ServiceMethod<T> serviceMethod, Object[] args) {
this.serviceMethod = serviceMethod;
this.args = args;
}
...
}
核心3-CallAdapter.adapt()
return serviceMethod.callAdapter.adapt(okHttpCall);
serviceMethod.callAdapter的创建是在serviceMethod的build()方法中去创建的。而adapt方法前面也提过,就是把Retrofit中的每一个call转换成其他平台也可以使用的类型(比如rxjava中就被转换成rxjava所使用的类型)。
2.拿到动态代理对象,预备执行网络请求
通过第1点的Retrofit.create(接口类),我们知道返回的是动态代理的接口类,即
Api api=retrofit.create(Api.class);
此时当我们调用接口中的方法,比如:
Call call=api.getCall();
此时的call就是动态代理后返回给我们的OKhttpCall,且OKhttpCall是对okhttp网络库的封装,这样就串联了起来,后面再看看真正的请求的同步和异步执行。
3.OKhttpCall执行请求
分为:同步execute和异步enqueue请求
1)execute
public Response<T> execute() throws IOException {
//底层的okhttp的call
okhttp3.Call call;
synchronized (this) {
if (executed) throw new IllegalStateException("Already executed.");
//已执行的标志
executed = true;
...
call = rawCall;
if (call == null) {
try {
//下方讲解
call = rawCall = createRawCall();
} catch (IOException | RuntimeException e) {
creationFailure = e;
throw e;
}
}
}
//通过标志位取消请求
if (canceled) {
call.cancel();
}
//okhttp库请求得到数据,并在解析后被返回
return parseResponse(call.execute());
}
看看call的创建->createRawCall()
private okhttp3.Call createRawCall() throws IOException {
//生成request 如何生成,待会看看
Request request = serviceMethod.toRequest(args);
//生成okhttp3.Call
okhttp3.Call call = serviceMethod.callFactory.newCall(request);
if (call == null) {
throw new NullPointerException("Call.Factory returned null.");
}
return call;
}
看Request如何生成:
Request toRequest(Object... args) throws IOException {
RequestBuilder requestBuilder = new RequestBuilder(httpMethod, baseUrl, relativeUrl, headers,
contentType, hasBody, isFormEncoded, isMultipart);
...
//ParameterHandler解析
ParameterHandler<Object>[] handlers = (ParameterHandler<Object>[]) parameterHandlers;
...
return requestBuilder.build();
}
在看看serviceMethod.callFactory.newCall(request),发现最终调用的是:
protected RealCall(OkHttpClient client, Request originalRequest) {
this.client = client;
this.originalRequest = originalRequest;
}
而RealCall是okhttp库中的call的实现类,代表此时的网络请求已交给okhttp处理。
在看看execute最后返回的数据,parseResponse(call.execute()):
Response<T> parseResponse(okhttp3.Response rawResponse) throws IOException {
ResponseBody rawBody = rawResponse.body();
...
//响应码判断
int code = rawResponse.code();
if (code < 200 || code >= 300) {
...
}
if (code == 204 || code == 205) {
...
}
ExceptionCatchingRequestBody catchingBody = new ExceptionCatchingRequestBody(rawBody);
try {
//处理响应体
T body = serviceMethod.toResponse(catchingBody);
//处理后的数据,返回给retrofit的成功响应回调
return Response.success(body, rawResponse);
} catch (RuntimeException e) {
catchingBody.throwIfCaught();
throw e;
}
}
进入serviceMethod.toResponse(catchingBody):
T toResponse(ResponseBody body) throws IOException {
//调用数据转换器转换响应数据
return responseConverter.convert(body);
}
流程总结:由ParameterHandler对接口方法和方法参数进行解析 -> 将请求所需信息封装到ServiceMethod -> 根据ServiceMethod 创建okhttp的request -> 用okhttpcall(底层okhttp)执行请求 -> converter解析最终返回数据
2)enqueue()
public void enqueue(final Callback<T> callback) {
...
okhttp3.Call call;
Throwable failure;
synchronized (this) {
...
//已执行标志位
executed = true;
call = rawCall;
failure = creationFailure;
if (call == null && failure == null) {
try {
//内部创建request和call,返回call
call = rawCall = createRawCall();
} catch (Throwable t) {
failure = creationFailure = t;
}
}
}
...
//取消请求
if (canceled) {
call.cancel();
}
call.enqueue(new okhttp3.Callback() {
@Override public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse)
throws IOException {
Response<T> response;
try {
//将解析后的响应数据赋值response
response = parseResponse(rawResponse);
} catch (Throwable e) {
callFailure(e);
return;
}
//回调返回数据
callSuccess(response);
}
@Override public void onFailure(okhttp3.Call call, IOException e) {
try {
//失败回调
callback.onFailure(OkHttpCall.this, e);
} catch (Throwable t) {
t.printStackTrace();
}
}
private void callFailure(Throwable e) {
try {
//失败回调
callback.onFailure(OkHttpCall.this, e);
} catch (Throwable t) {
t.printStackTrace();
}
}
private void callSuccess(Response<T> response) {
try {
//成功回调
callback.onResponse(OkHttpCall.this, response);
} catch (Throwable t) {
t.printStackTrace();
}
}
});
}