Android-Retrofit
2020-03-03 本文已影响0人
写代码的阿毛
概述
- Retrofit 通过注解将
Java Interface API
调用转化为HTTP Call
,注解提供了HTTP Call
的参数; - 使用者可以适配请求参数转化,响应数据转化,
HTTP Call
对象转化,OkHttpClient
定制等; - 源码基于retrofit-2.7.1;
Converter
-
Converter
public interface Converter<F, T> { @Nullable T convert(F value) throws IOException; }
- 用于将
F
类型的对象转化为T
类型的对象;
- 用于将
-
Converter.Factory
abstract class Factory { //生成 Converter 对象,将 ResponseBody 类型转化为 Type 类型; public @Nullable Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) { return null; } //生成 Converter 对象,将 Type 类型转化为 RequestBody 类型; public @Nullable Converter<?, RequestBody> requestBodyConverter(Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) { return null; } //生成 Converter 对象,将 Type 类型转化为 String 类型 public @Nullable Converter<?, String> stringConverter(Type type, Annotation[] annotations, Retrofit retrofit) { return null; } //返回参数化类型中的类型引元的上界类型 protected static Type getParameterUpperBound(int index, ParameterizedType type) { return Utils.getParameterUpperBound(index, type); } //返回原生类型 protected static Class<?> getRawType(Type type) { return Utils.getRawType(type); } }
-
responseBodyConverter
生成Converter
,将ResponseBody
转化为Type
; -
requestBodyConverter
生成Converter
,将Type
转化为RequestBody
;用于转化用Body
Part
PartMap
注解的参数; -
stringConverter
生成Converter
,将Type
转化为String
;用于转化用Field
FieldMap
Header
HeaderMap
Path
Query
QueryMap
注解的参数;
-
CallAdapter
-
CallAdapter
//将 Call<R> 转化为 T 的适配器 public interface CallAdapter<R, T> { //返回 response type Type responseType(); //将 Call<R> 转化为T T adapt(Call<R> call); }
-
CallAdapter.Factory
abstract class Factory { //生成 CallAdapter public abstract @Nullable CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit); //返回参数化类型的类型引元的上界类型 protected static Type getParameterUpperBound(int index, ParameterizedType type) { return Utils.getParameterUpperBound(index, type); } //返回原生类型 protected static Class<?> getRawType(Type type) { return Utils.getRawType(type); } }
- 返回匹配的 CallAdapter
ServiceMethod
-
ServiceMethod
可以理解为Java Interface API
的静态映射; - 生成
ServiceMethod
abstract class ServiceMethod<T> { static <T> ServiceMethod<T> parseAnnotations(Retrofit retrofit, Method method) { //解析 Annotation ,生成RequestFactory RequestFactory requestFactory = RequestFactory.parseAnnotations(retrofit, method); //返回类型不支持泛型或者通配符类型 Type returnType = method.getGenericReturnType(); if (Utils.hasUnresolvableType(returnType)) { throw methodError(method, "Method return type must not include a type variable or wildcard: %s", returnType); } //返回类型不支持 void 类型 if (returnType == void.class) { throw methodError(method, "Service methods cannot return void."); } //生成 ServiceMethod return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory); } abstract @Nullable T invoke(Object[] args); } static RequestFactory parseAnnotations(Retrofit retrofit, Method method) { //通过 Method 生成 RequestFactory,RequestFactory#create 可以生成最终发起请求的 Request return new Builder(retrofit, method).build(); } static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations( Retrofit retrofit, Method method, RequestFactory requestFactory) { boolean isKotlinSuspendFunction = requestFactory.isKotlinSuspendFunction; boolean continuationWantsResponse = false; boolean continuationBodyNullable = false; Annotation[] annotations = method.getAnnotations(); Type adapterType; if (isKotlinSuspendFunction) { //kotlin 挂起函数 相关逻辑 } else { // Method 返回类型(包括类型引元) adapterType = method.getGenericReturnType(); } //根据 adapterType 找到匹配的 CallAdapter CallAdapter<ResponseT, ReturnT> callAdapter = createCallAdapter(retrofit, method, adapterType, annotations); //返回 CallAdapter 指定的 responseType Type responseType = callAdapter.responseType(); //根据 responseType 找到匹配的Converter Converter<ResponseBody, ResponseT> responseConverter = createResponseConverter(retrofit, method, responseType); okhttp3.Call.Factory callFactory = retrofit.callFactory; if (!isKotlinSuspendFunction) { //生成ServiceMethod return new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter); } else if (continuationWantsResponse) { //noinspection unchecked Kotlin compiler guarantees ReturnT to be Object. return (HttpServiceMethod<ResponseT, ReturnT>) new SuspendForResponse<>(requestFactory, callFactory, responseConverter, (CallAdapter<ResponseT, Call<ResponseT>>) callAdapter); } else { //noinspection unchecked Kotlin compiler guarantees ReturnT to be Object. return (HttpServiceMethod<ResponseT, ReturnT>) new SuspendForBody<>(requestFactory, callFactory, responseConverter, (CallAdapter<ResponseT, Call<ResponseT>>) callAdapter, continuationBodyNullable); } }
-
RequestFactory#parseAnnotations
通过Method
生成RequestFactory
;RequestFactory#create
生成最终发起请求的Request
; -
RequestFactory.Builder
中关于各种注解的解析,可自行查看源码; -
ServiceMethod#parseAnnotations
- 先通过
Method
的返回类型(包括类型引元)找到匹配的CallAdapter
; - 再通过
CallAdapter#responseAdapter
找到匹配的响应数据的Converter
; - 通过
RequestFactory
Call.Factory
Converter
CallAdapter
生成CallAdapted
,CallAdapted
是ServiceMethod
的子类;
- 先通过
-
-
ServiceMethod
的调用ReturnT invoke(Object[] args) { Call<ResponseT> call = new OkHttpCall<>(requestFactory, args, callFactory, responseConverter); return adapt(call, args); } @Override protected ReturnT adapt(Call<ResponseT> call, Object[] args) { return callAdapter.adapt(call); }
-
Java Interface API
的调用就是ServiceMethod
的调用,即调用ServiceMethod#invoke
; - 根据
RequestFactory
Call.Factory
Converter
生成OkHttpCall
,内部持有Okhttp
的Call
,所以Retrofit
的网络请求是由OkHttp
处理的,并且无法更改; - 根据
CallAdapter
返回Java Interface API
的返回类型的对象,并把OkHttpCall
通过参数传递给CallAdapter
;
-
Retrofit
-
Retrofit/Builder
-
Retrofit
对象是通过Retrofit.Builder
生成的,有各种配置项;
//缓存接口方法对应的 ServiceMethod private final Map<Method, ServiceMethod<?>> serviceMethodCache = new ConcurrentHashMap<>(); //通过 Factory 生成的 Call 对象发起网络请求 final okhttp3.Call.Factory callFactory; //用于拼接url final HttpUrl baseUrl; //请求数据/响应数据 final List<Converter.Factory> converterFactories; // HTTP Call 对象转化器 final List<CallAdapter.Factory> callAdapterFactories; //异步回调分发器 final @Nullable Executor callbackExecutor; //ServiceMethod预加载 final boolean validateEagerly;
-
serviceMethodCache
用于缓存Java Interface API
对应的ServiceMethod
; -
callFactory
用于生成真正发情网络请求的HTTP Call
;默认会创建一个OkHttpClient
; -
converterFactories
用于生成 请求数据/响应数据 转化器;要注意添加Converter.Factory
的顺序; -
callAdapterFactories
用于生成HTTP Call
适配器,将Retrofit
内置的HTTP Call
转化为Java Interface API
返回的HTTP Call
;要注意添加CallAdapter
的顺序; -
callbackExecutor
表示异步回调分发器;默认是主线程; -
validateEagerly
表示是否预加载ServiceMethod
;如果为true
,则在创建Java Interfae
对应的动态代理对象时,预加载该Java Interface
所有 API 对应的ServiceMethod
;
-
-
Retrofit#create
public <T> T create(final Class<T> service) { // Java Interface 校验,ServiceMethod 预加载 validateServiceInterface(service); //生成动态代理对象 return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service }, new InvocationHandler() { private final Platform platform = Platform.get(); private final Object[] emptyArgs = new Object[0]; @Override public @Nullable Object invoke(Object proxy, Method method, @Nullable Object[] args) throws Throwable { // 如果是 Object 的 API 调用,直接调用 if (method.getDeclaringClass() == Object.class) { return method.invoke(this, args); } // 如果是 Java Interface 中的默认方法调用 if (platform.isDefaultMethod(method)) { return platform.invokeDefaultMethod(method, service, proxy, args); } // 通过 ServiceMethod 代理调用 return loadServiceMethod(method).invoke(args != null ? args : emptyArgs); } }); } private void validateServiceInterface(Class<?> service) { // 指定的类必须为 Interface if (!service.isInterface()) { throw new IllegalArgumentException("API declarations must be interfaces."); } Deque<Class<?>> check = new ArrayDeque<>(1); check.add(service); while (!check.isEmpty()) { Class<?> candidate = check.removeFirst(); if (candidate.getTypeParameters().length != 0) { //不支持参数化类型 StringBuilder message = new StringBuilder("Type parameters are unsupported on ") .append(candidate.getName()); if (candidate != service) { message.append(" which is an interface of ") .append(service.getName()); } throw new IllegalArgumentException(message.toString()); } Collections.addAll(check, candidate.getInterfaces()); } // ServiceMethod 预加载 if (validateEagerly) { Platform platform = Platform.get(); for (Method method : service.getDeclaredMethods()) { if (!platform.isDefaultMethod(method) && !Modifier.isStatic(method.getModifiers())) { //加载 ServiceMethod loadServiceMethod(method); } } } } ServiceMethod<?> loadServiceMethod(Method method) { //如果有缓存,直接返回 ServiceMethod<?> result = serviceMethodCache.get(method); if (result != null) return result; synchronized (serviceMethodCache) { result = serviceMethodCache.get(method); if (result == null) { //通过 Method 及相关注解,生成 ServiceMethod 对象,并缓存 result = ServiceMethod.parseAnnotations(this, method); serviceMethodCache.put(method, result); } } return result; }
- 先校验指定的
Class
,必须为Java Interface
,并且不是参数化类型;如果要预加载ServiceMethod
,则通过Method
及相关的Annotation
生成ServiceMethod
并缓存; - 通过动态代理为指定的
Java Interface
生成动态代理对象,动态代理可以查看 Java-反射-动态代理 ; - 动态代理对象的方法调用都会转发给绑定的
InvocationHandler#invoke
方法;具体调用流程后面会有详细介绍;
- 先校验指定的
-
Retrofit#callAdapter
//返回匹配 Java Interface API 返回类型的 CallAdapter public CallAdapter<?, ?> callAdapter(Type returnType, Annotation[] annotations) { return nextCallAdapter(null, returnType, annotations); } //返回匹配 Java Interface API 返回类型的 CallAdapter public CallAdapter<?, ?> nextCallAdapter(@Nullable CallAdapter.Factory skipPast, Type returnType, Annotation[] annotations) { Objects.requireNonNull(returnType, "returnType == null"); Objects.requireNonNull(annotations, "annotations == null"); int start = callAdapterFactories.indexOf(skipPast) + 1; for (int i = start, count = callAdapterFactories.size(); i < count; i++) { CallAdapter<?, ?> adapter = callAdapterFactories.get(i).get(returnType, annotations, this); if (adapter != null) { //CallAdapter.Factory 返回不为null,则匹配成功 return adapter; } } }
- 从
callAdapterFactories
中遍历寻找能匹配returnType
的CallAdapter;
- 从
-
Retrofit#requestBodyConverter
// 返回 requestBody 的转化器 public <T> Converter<T, RequestBody> requestBodyConverter(Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations) { return nextRequestBodyConverter(null, type, parameterAnnotations, methodAnnotations); } // 返回 requestBody 的转化器 public <T> Converter<T, RequestBody> nextRequestBodyConverter( @Nullable Converter.Factory skipPast, Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations) { int start = converterFactories.indexOf(skipPast) + 1; for (int i = start, count = converterFactories.size(); i < count; i++) { Converter.Factory factory = converterFactories.get(i); Converter<?, RequestBody> converter = factory.requestBodyConverter(type, parameterAnnotations, methodAnnotations, this); if (converter != null) { //如果返回的 Converter 不为null,则匹配成功 return (Converter<T, RequestBody>) converter; } } }
- 返回转化 requestBody 的
Converter
; - 用于转化用
Body
Part
PartMap
注解的方法参数;
- 返回转化 requestBody 的
-
Retrofit#responseBodyConverter
//返回 public <T> Converter<ResponseBody, T> responseBodyConverter(Type type, Annotation[] annotations) { return nextResponseBodyConverter(null, type, annotations); } public <T> Converter<ResponseBody, T> nextResponseBodyConverter( @Nullable Converter.Factory skipPast, Type type, Annotation[] annotations) { 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) { //如果返回 Converter 不为null,则匹配成功 return (Converter<ResponseBody, T>) converter; } } }
- 返回转化 responseBody 的
Converter
;
- 返回转化 responseBody 的
-
Retrofit#stringConverter
//返回 `Conterver` ,用于将 `Type` 转化为 `String` ; public <T> Converter<T, String> stringConverter(Type type, Annotation[] annotations) { for (int i = 0, count = converterFactories.size(); i < count; i++) { Converter<?, String> converter = converterFactories.get(i).stringConverter(type, annotations, this); if (converter != null) { //noinspection unchecked return (Converter<T, String>) converter; } } //如果没有匹配到,则返回内置的 Converter return (Converter<T, String>) BuiltInConverters.ToStringConverter.INSTANCE; }
- 返回
Converter
,用于将Type
转化为String
; - 用于转化用
Field
FieldMap
Header
HeaderMap
Path
Query
QueryMap
注解的方法参数;
- 返回
总结
-
Retrofit
整体分为两部分:注解和代码;- 注解部分
- 在
Java Interfae API
中说明该网络请求的参数,包括请求方法(GET,POST等),请求参数,URL等;
- 在
- 代码部分
- 把
Java Interface API
转换成对应的ServiceMethod
:根据设置的Converter.Factory
CallAdapter.Factory
找到匹配的CallAdapter
Converter
,生成RequestFactory
; -
Java Interface API
调用时,根据ServiceMethod
中的RequestFactory
Converter
以及传入的参数,生成OkHttpCall
,并将CallAdapter
转换后的结果返回;
- 把
- 注解部分
-
Converter.Factory
中的requestBodyConverter
比较独立;Converter.Factory
中的responseBodyConverter
与CallAdapter.Factory
中的responseType
是关联的,表示的是响应数据要转换的类型; - 配置
CallAdapterFactory
ConverterFactory
时,需要注意前后顺序,具有特殊性的要排在前面,防止前面的通用性的 Factory 覆盖了 后面的 Factory ; - 关于解析注解的那部分,感兴趣的可以自行查看源码
RequestFactory#parseAnnotations
,里面涉及 HTTP 协议的知识;
其他
- 多个 baseUrl 配置
- 如果涉及
OkHttpClient
配置不一样的,或者不同module之间,可以多个Retrofit
;如果只是少数几个接口不一样,可以通过Url
注解第一个参数动态设置 或者 注解方法时指定绝对路径静态设置; - 关于不同环境下的 baseUrl 切换,可以放在
OkHttpClient
的Interceptor
中动态切换;
- 如果涉及