前言
现代Android开发中,Retrofit是主流的网络请求框架,内部封装OkHttp发起请求,也是声明式Http客户端,使用接口 + 注解的方式在接口中编写请求方法。
简单使用
先看下常规Retrofit的使用吧,也是通过入口API来看源码的一种好方法。
我们先来看不添加Convert转换器的方式,这种方式只能设置返回值中的泛型为ResponseBody,拿到的数据只能是Json字符串,而转换模型的操作需要我们自己做,当然如果是添加了转换器,则可以直接写模型的泛型了
- 编写请求方法的接口
public interface WanAndroid {
/**
* Retrofit Call,获取首页文章列表,如果不添加转换器,则泛型只能是ResponseBody
*/
@GET("article/list/{page}/json")
Call<ResponseBody> getHomeArticleByCall(@Path("page") int page);
}
- 创建Retroft实例
//创建Retrofit实例
Retrofit retrofit = new Retrofit.Builder()
//配置OkHttpClient
.callFactory(new OkHttpClient.Builder().build())
//配置基础Url
.baseUrl("https://www.wanandroid.com")
//开始创建
.build();
//创建服务接口
WanAndroid wanAndroid = mRetrofit.create(WanAndroid.class);
- 发起请求,没有添加转换器,需要自己做转换,代码太恶心了
wanAndroid.getHomeArticleByCall(page).enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
try {
//解析Json,转换为模型
String json = response.body().string();
Gson gson = new Gson();
Type type = new TypeToken<HttpModel<PageModel<HomeArticleModel>>>() {
}.getType();
HttpModel<PageModel<HomeArticleModel>> model = gson.fromJson(json, type);
//请求成功
} catch (IOException e) {
e.printStackTrace();
//请求失败
}
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable throwable) {
ToastUtil.toast(getContext(), "请求失败:" + throwable.getMessage());
}
});
开始分析
从简单使用来看,我们发现以下几点
- Retrofit的实例创建,通过Builder构建者模式,通过链式编程进行Retrofit的配置,最后通过build()方法创建实例
- 请求的方法,都放在接口上,通过Retrofit的create()方法,创建接口的实例
- API接口的方法返回值为Call,它是Retrofit中的一个类
Retrofit实例创建
简单来讲,就是把Retrofit的构造方法私有,只能通过内部的Builder内部类的实例创建,所以我们对Retrofit的配置,都是配置到Retrofit内的Builder类后,再通过它的build方法,创建Retrofit实例。
public final class Retrofit {
/**
* OkHttpClient
*/
final okhttp3.Call.Factory callFactory;
/**
* 基础Url
*/
final HttpUrl baseUrl;
/**
* Converter转换器工厂列表
*/
final List<Converter.Factory> converterFactories;
/**
* CallAdapter适配器工厂列表
*/
final List<CallAdapter.Factory> callAdapterFactories;
/**
* 回调执行器
*/
final @Nullable
Executor callbackExecutor;
/**
* 是否创建接口实例时就校验接口的合法性,默认为false,在调用接口的方法时,才校验
*/
final boolean validateEagerly;
Retrofit(
okhttp3.Call.Factory callFactory,
HttpUrl baseUrl,
List<Converter.Factory> converterFactories,
List<CallAdapter.Factory> callAdapterFactories,
@Nullable Executor callbackExecutor,
boolean validateEagerly) {
this.callFactory = callFactory;
this.baseUrl = baseUrl;
this.converterFactories = converterFactories; // Copy+unmodifiable at call site.
this.callAdapterFactories = callAdapterFactories; // Copy+unmodifiable at call site.
this.callbackExecutor = callbackExecutor;
this.validateEagerly = validateEagerly;
}
/**
* 使用Builder构建者模式
*/
public static final class Builder {
/**
* 平台
*/
private final Platform platform;
/**
* OkHttpClient
*/
private @Nullable
okhttp3.Call.Factory callFactory;
/**
* 基础路径
*/
private @Nullable
HttpUrl baseUrl;
/**
* 注册的Converter转换器工厂
*/
private final List<Converter.Factory> converterFactories = new ArrayList<>();
/**
* 注册的CallAdapter适配器工厂
*/
private final List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>();
/**
* 回调时使用的执行器
*/
private @Nullable
Executor callbackExecutor;
/**
* 是否马上检查API接口的合法性
*/
private boolean validateEagerly;
Builder(Platform platform) {
this.platform = platform;
}
public Builder() {
this(Platform.get());
}
/**
* 直接拷贝另外一个Retrofit实例的配置到Builder
*/
Builder(Retrofit retrofit) {
platform = Platform.get();
callFactory = retrofit.callFactory;
baseUrl = retrofit.baseUrl;
// Do not add the default BuiltIntConverters and platform-aware converters added by build().
for (int i = 1,
size = retrofit.converterFactories.size() - platform.defaultConverterFactoriesSize();
i < size;
i++) {
converterFactories.add(retrofit.converterFactories.get(i));
}
// Do not add the default, platform-aware call adapters added by build().
for (int i = 0,
size =
retrofit.callAdapterFactories.size() - platform.defaultCallAdapterFactoriesSize();
i < size;
i++) {
callAdapterFactories.add(retrofit.callAdapterFactories.get(i));
}
callbackExecutor = retrofit.callbackExecutor;
validateEagerly = retrofit.validateEagerly;
}
/**
* 设置OkHttpClient
*/
public Builder client(OkHttpClient client) {
return callFactory(Objects.requireNonNull(client, "client == null"));
}
/**
* 设置OkHttpClient
*/
public Builder callFactory(okhttp3.Call.Factory factory) {
this.callFactory = Objects.requireNonNull(factory, "factory == null");
return this;
}
/**
* 配置URL类型的基础Url
*/
public Builder baseUrl(URL baseUrl) {
Objects.requireNonNull(baseUrl, "baseUrl == null");
return baseUrl(HttpUrl.get(baseUrl.toString()));
}
/**
* 配置String类型基础Url
*/
public Builder baseUrl(String baseUrl) {
Objects.requireNonNull(baseUrl, "baseUrl == null");
return baseUrl(HttpUrl.get(baseUrl));
}
/**
* 配置HttpUrl类型基础Url
*/
public Builder baseUrl(HttpUrl baseUrl) {
Objects.requireNonNull(baseUrl, "baseUrl == null");
List<String> pathSegments = baseUrl.pathSegments();
if (!"".equals(pathSegments.get(pathSegments.size() - 1))) {
throw new IllegalArgumentException("baseUrl must end in /: " + baseUrl);
}
this.baseUrl = baseUrl;
return this;
}
/**
* 添加一个Converter工厂
*/
public Builder addConverterFactory(Converter.Factory factory) {
converterFactories.add(Objects.requireNonNull(factory, "factory == null"));
return this;
}
/**
* 添加一个CallAdapter工厂
*/
public Builder addCallAdapterFactory(CallAdapter.Factory factory) {
callAdapterFactories.add(Objects.requireNonNull(factory, "factory == null"));
return this;
}
/**
* 配置回调执行器
*/
public Builder callbackExecutor(Executor executor) {
this.callbackExecutor = Objects.requireNonNull(executor, "executor == null");
return this;
}
/**
* 返回注册的CallAdapter工厂
*/
public List<CallAdapter.Factory> callAdapterFactories() {
return this.callAdapterFactories;
}
/**
* 返回注册的Converter工厂
*/
public List<Converter.Factory> converterFactories() {
return this.converterFactories;
}
/**
* 配置是否迫切校验接口上的方法
*/
public Builder validateEagerly(boolean validateEagerly) {
this.validateEagerly = validateEagerly;
return this;
}
/**
* 构建一个Retrofit实例
*/
public Retrofit build() {
//必须设置基础路径
if (baseUrl == null) {
throw new IllegalStateException("Base URL required.");
}
okhttp3.Call.Factory callFactory = this.callFactory;
//外部没有配置,创建默认配置的OkHttpClient
if (callFactory == null) {
callFactory = new OkHttpClient();
}
//外部没有配置,自动从平台中拿
Executor callbackExecutor = this.callbackExecutor;
if (callbackExecutor == null) {
callbackExecutor = platform.defaultCallbackExecutor();
}
// Make a defensive copy of the adapters and add the default Call adapter.
List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
//默认添加一个CallAdapter工厂,支持Call类型的返回值
callAdapterFactories.addAll(platform.defaultCallAdapterFactories(callbackExecutor));
// Make a defensive copy of the converters.
List<Converter.Factory> converterFactories =
new ArrayList<>(
1 + this.converterFactories.size() + platform.defaultConverterFactoriesSize());
// Add the built-in converter factory first. This prevents overriding its behavior but also
// ensures correct behavior when using converters that consume all types.
//默认添加一个Converter工厂,支持返回值的泛型为RequestBody类型
converterFactories.add(new BuiltInConverters());
converterFactories.addAll(this.converterFactories);
//从平台中拿Converter工厂,不同平台可以有不同的支持,如果支持Java8,则会添加一个Option类型的支持
converterFactories.addAll(platform.defaultConverterFactories());
//创建实例
return new Retrofit(
callFactory,
baseUrl,
unmodifiableList(converterFactories),
unmodifiableList(callAdapterFactories),
callbackExecutor,
validateEagerly);
}
}
}
- Platform类,请求响应回调在主线程的关键
在Builder的构造方法中,调用了Platform类的get方法,这个类是适配调用平台的,因为Retrofit的接口请求在子线程请求,而接口响应的回调方法,是可以在Android的主线程中回调的,这就肯定会涉及到Handler,而Retrofit也支持在鸿蒙上使用,这时就需要拓展Platfrom类来实现
可以看到,如果在Android平台运行,则返回的是Android实现类,该类复写了defaultCallbackExecutor()
方法,返回MainThreadExecutor
实例,这个Executor其实是线程池接口,只有一个execute()
方法,MainThreadExecutor
类复写了execute()
方法,通过Handler把传进来的Runnable转发到主线程进行回调
class Platform {
/**
* 单例,查找到后,后续再调用不会再次查找
*/
private static final Platform PLATFORM = findPlatform();
/**
* 获取Platform实例的方法
*/
static Platform get() {
return PLATFORM;
}
/**
* 查找当前平台的实现
*/
private static Platform findPlatform() {
try {
Class.forName("android.os.Build");
//安卓
if (Build.VERSION.SDK_INT != 0) {
return new Android();
}
} catch (ClassNotFoundException ignored) {
//ignored
}
//Java8
return new Platform(true);
}
/**
* 是否支持Java8
*/
private final boolean hasJava8Types;
private final @Nullable
Constructor<Lookup> lookupConstructor;
Platform(boolean hasJava8Types) {
this.hasJava8Types = hasJava8Types;
Constructor<Lookup> lookupConstructor = null;
if (hasJava8Types) {
try {
// Because the service interface might not be public, we need to use a MethodHandle lookup
// that ignores the visibility of the declaringClass.
lookupConstructor = Lookup.class.getDeclaredConstructor(Class.class, int.class);
lookupConstructor.setAccessible(true);
} catch (NoClassDefFoundError ignored) {
// Android API 24 or 25 where Lookup doesn't exist. Calling default methods on non-public
// interfaces will fail, but there's nothing we can do about it.
} catch (NoSuchMethodException ignored) {
// Assume JDK 14+ which contains a fix that allows a regular lookup to succeed.
// See https://bugs.openjdk.java.net/browse/JDK-8209005.
}
}
this.lookupConstructor = lookupConstructor;
}
@Nullable
Executor defaultCallbackExecutor() {
return null;
}
List<? extends CallAdapter.Factory> defaultCallAdapterFactories(
@Nullable Executor callbackExecutor) {
//默认的CallAdapterFactory,支持Call类型的返回值
DefaultCallAdapterFactory executorFactory = new DefaultCallAdapterFactory(callbackExecutor);
return hasJava8Types
? asList(CompletableFutureCallAdapterFactory.INSTANCE, executorFactory)
: singletonList(executorFactory);
}
int defaultCallAdapterFactoriesSize() {
return hasJava8Types ? 2 : 1;
}
List<? extends Converter.Factory> defaultConverterFactories() {
return hasJava8Types ? singletonList(OptionalConverterFactory.INSTANCE) : emptyList();
}
int defaultConverterFactoriesSize() {
return hasJava8Types ? 1 : 0;
}
boolean isDefaultMethod(Method method) {
return hasJava8Types && method.isDefault();
}
@Nullable
Object invokeDefaultMethod(Method method, Class<?> declaringClass, Object object, Object... args)
throws Throwable {
Lookup lookup =
lookupConstructor != null
? lookupConstructor.newInstance(declaringClass, -1 /* trusted */)
: MethodHandles.lookup();
return lookup.unreflectSpecial(method, declaringClass).bindTo(object).invokeWithArguments(args);
}
static final class Android extends Platform {
Android() {
super(Build.VERSION.SDK_INT >= 24);
}
@Override
public Executor defaultCallbackExecutor() {
return new MainThreadExecutor();
}
@Nullable
@Override
Object invokeDefaultMethod(
Method method, Class<?> declaringClass, Object object, Object... args) throws Throwable {
if (Build.VERSION.SDK_INT < 26) {
throw new UnsupportedOperationException(
"Calling default methods on API 24 and 25 is not supported");
}
return super.invokeDefaultMethod(method, declaringClass, object, args);
}
/**
* 安卓主线程执行器
*/
static final class MainThreadExecutor implements Executor {
private final Handler handler = new Handler(Looper.getMainLooper());
@Override
public void execute(Runnable task) {
handler.post(task);
}
}
}
}
API接口实例创建
Http接口的实现,是通过create()
方法创建的,内部使用的是JDK的动态代理,当我们调用代理类的方法时,会回调InvocationHandler
的invoke()
方法
- create(),动态代理接口的实现
/**
* 传入一个API接口类的Class,动态代理该接口的实例
*/
@SuppressWarnings("unchecked")
public <T> T create(final Class<T> service) {
//检查接口中的方法的合法性
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的方法,直接调用,不需要处理
if (method.getDeclaringClass() == Object.class) {
return method.invoke(this, args);
}
//没有参数,也用一个空数组
args = args != null ? args : emptyArgs;
//如果是default默认方法,直接调用
return platform.isDefaultMethod(method) ? platform.invokeDefaultMethod(method, service, proxy, args)
//普通方法,进行加载和解析,然后进行调用
: loadServiceMethod(method).invoke(args);
}
});
}
- validateServiceInterface(),检查API接口的合法性
/**
* 检查API接口Class
*/
private void validateServiceInterface(Class<?> service) {
//传入的Class必须是接口类
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());
}
//是否创建的时候就校验,默认为false,当调用接口方法时才校验,如果配置为true,则创建接口代理实现类时就校验
if (validateEagerly) {
Platform platform = Platform.get();
//遍历接口上的方法
for (Method method : service.getDeclaredMethods()) {
//不检查default默认方法和静态方法
if (!platform.isDefaultMethod(method) && !Modifier.isStatic(method.getModifiers())) {
loadServiceMethod(method);
}
}
}
}
- loadServiceMethod(),加载接口方法
在InvocationHandler
类的invoke()
方法中,如果调用的是Object类的方法,直接调用,如果是Java8的默认方法,直接调用。最后就是普通的API方法,则调用loadServiceMethod()
,这个方法的作用是解析API方法,并缓存到一个Map中,下次调用是直接复用的,最终是需要返回一个不为null的ServiceMethod
实例,再调用它的invoke()
执行方法调用
/**
* 接口方法信息的缓存
*/
private final Map<Method, ServiceMethod<?>> serviceMethodCache = new ConcurrentHashMap<>();
/**
* 加载接口方法
*/
ServiceMethod<?> loadServiceMethod(Method method) {
//优先从缓存中取,取得到则返回,不需要每次调用都处理一次,浪费性能
ServiceMethod<?> result = serviceMethodCache.get(method);
if (result != null) {
return result;
}
//Double Check + 同步锁,确保多线程调用时真的找不到缓存
synchronized (serviceMethodCache) {
result = serviceMethodCache.get(method);
if (result == null) {
//真的没有,解析方法上的注解
result = ServiceMethod.parseAnnotations(this, method);
//解析完,放到缓存
serviceMethodCache.put(method, result);
}
}
return result;
}
- ServiceMethod.parseAnnotations,解析方法上的注解
loadServiceMethod ()
中,如果没有命中缓存,则通过ServiceMethod.parseAnnotations()
,解析方法注解,返回ServiceMethod
实例,再缓存起来
其中,ServiceMethod
是一个抽象类
abstract class ServiceMethod<T> {
/**
* 解析注解
*/
static <T> ServiceMethod<T> parseAnnotations(Retrofit retrofit, Method method) {
//解析接口上的请求方法的注解,以及方法形参上的注解,并把信息转换为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.");
}
//进行返回值适配和转换器
return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
}
/**
* 执行方法
*
* @param args 方法参数
*/
abstract @Nullable
T invoke(Object[] args);
}
- RequestFactory.parseAnnotations(),解析接口上的请求方法的注解,以及方法形参上的注解,并把信息转换为RequestFactory实例
RequestFactory
类也是一个Builder建造者模式,只是它是通过Builder
类拆解Method
对象,再通过build
方法开始解析方法上的注解
注解分2种,分别是:方法级的注解
和方法形参上的注解
,方法级的注解
是@GET
、@POST
这种作用于方法上的注解,而方法形参上的注解
则是@Path
、@Field
这种作用于形参上的注解
最后返回RequestFactory
实例,最后调用HttpServiceMethod.parseAnnotations()
,进行返回值适配和转换器
final class RequestFactory {
/**
* 解析方法上的注解
*/
static RequestFactory parseAnnotations(Retrofit retrofit, Method method) {
//把方法上的注解进行解析,并封装到RequestFactory类上
return new Builder(retrofit, method).build();
}
static final class Builder {
private static final String PARAM = "[a-zA-Z][a-zA-Z0-9_-]*";
private static final Pattern PARAM_URL_REGEX = Pattern.compile("\\{(" + PARAM + ")\\}");
private static final Pattern PARAM_NAME_REGEX = Pattern.compile(PARAM);
final Retrofit retrofit;
final Method method;
final Annotation[] methodAnnotations;
final Annotation[][] parameterAnnotationsArray;
final Type[] parameterTypes;
boolean gotField;
boolean gotPart;
boolean gotBody;
boolean gotPath;
boolean gotQuery;
boolean gotQueryName;
boolean gotQueryMap;
boolean gotUrl;
@Nullable
String httpMethod;
boolean hasBody;
boolean isFormEncoded;
boolean isMultipart;
@Nullable
String relativeUrl;
@Nullable
Headers headers;
@Nullable
MediaType contentType;
@Nullable
Set<String> relativeUrlParamNames;
@Nullable
ParameterHandler<?>[] parameterHandlers;
/**
* 把方法上的注解、返回值、方法形参上的注解保存
*/
Builder(Retrofit retrofit, Method method) {
this.retrofit = retrofit;
this.method = method;
this.methodAnnotations = method.getAnnotations();
this.parameterTypes = method.getGenericParameterTypes();
this.parameterAnnotationsArray = method.getParameterAnnotations();
}
/**
* 开始解析
*/
RequestFactory build() {
//解析方法级的注解
for (Annotation annotation : methodAnnotations) {
parseMethodAnnotation(annotation);
}
//方法必须加上请求方式的注解,例如GET、POST
if (httpMethod == null) {
throw methodError(method, "HTTP method annotation is required (e.g., @GET, @POST, etc.).");
}
//没有Body
if (!hasBody) {
//不能是文件请求,肯定是使用了@GET注解,必须要使用@POST
if (isMultipart) {
throw methodError(
method,
"Multipart can only be specified on HTTP methods with request body (e.g., @POST).");
}
//不能是表单请求(表单请求是放在body上的)
if (isFormEncoded) {
throw methodError(
method,
"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, lastParameter = parameterCount - 1; p < parameterCount; p++) {
//解析方法形参上的注解
parameterHandlers[p] = parseParameter(p, parameterTypes[p], parameterAnnotationsArray[p]);
}
//不是相对路径的Url,必须添加@Url注解,指定完全路径的Url
if (relativeUrl == null && !gotUrl) {
throw methodError(method, "Missing either @%s URL or @Url parameter.", httpMethod);
}
//没有请求体的请求方式,不能加@Body注解
if (!isFormEncoded && !isMultipart && !hasBody && gotBody) {
throw methodError(method, "Non-body HTTP method cannot contain @Body.");
}
//表单请求,必须要有一个参数要有@Field的参数
if (isFormEncoded && !gotField) {
throw methodError(method, "Form-encoded method must contain at least one @Field.");
}
//文件请求,必须要有一个参数要有@Field的参数
if (isMultipart && !gotPart) {
throw methodError(method, "Multipart method must contain at least one @Part.");
}
return new RequestFactory(this);
}
}
}
- HttpServiceMethod.parseAnnotations,进行返回值适配和转换器
ServiceMethod
是一个抽象类,通过ServiceMethod.parseAnnotations()
静态方法,会返回其子类HttpServiceMethod
,子类的创建则是通过HttpServiceMethod.parseAnnotations()
创建
通过解析方法的返回值,调用createCallAdapter()
,查找能适配返回值的CallAdapter
,再调用createResponseConverter()
查找对应的Converter
转换器
发现,HttpServiceMethod
也是一个抽象类,它在ServiceMethod
的invoke()
基础上,调用了一个adapt()
抽象方法,其子类CallAdapted
,复写了该方法,最终invoke()
方法是通过CallAdapter
来进行处理
/**
* 一个把接口上的方法,转换为Http调用的ServiceMethod
*/
abstract class HttpServiceMethod<ResponseT, ReturnT> extends ServiceMethod<ReturnT> {
private final RequestFactory requestFactory;
private final okhttp3.Call.Factory callFactory;
private final Converter<ResponseBody, ResponseT> responseConverter;
HttpServiceMethod(
RequestFactory requestFactory,
okhttp3.Call.Factory callFactory,
Converter<ResponseBody, ResponseT> responseConverter) {
this.requestFactory = requestFactory;
this.callFactory = callFactory;
this.responseConverter = responseConverter;
}
/**
* 解析方法上的注解
*/
static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations(
Retrofit retrofit, Method method, RequestFactory requestFactory) {
//获取方法上的注解和返回值
Annotation[] annotations = method.getAnnotations();
Type adapterType = method.getGenericReturnType();
//找到支持适配返回值类型的CallAdapter
CallAdapter<ResponseT, ReturnT> callAdapter = createCallAdapter(retrofit, method, adapterType, annotations);
Type responseType = callAdapter.responseType();
//泛型不能为okhttp3的Response,你会不会是想要ResponseBody
if (responseType == okhttp3.Response.class) {
throw methodError(
method,
"'"
+ getRawType(responseType).getName()
+ "' is not a valid response body type. Did you mean ResponseBody?");
}
//Response必须要有泛型
if (responseType == Response.class) {
throw methodError(method, "Response must include generic type (e.g., Response<String>)");
}
// TODO support Unit for Kotlin?
//顶层方法必须没有返回值,例如public void static main() {}
if (requestFactory.httpMethod.equals("HEAD") && !Void.class.equals(responseType)) {
throw methodError(method, "HEAD method must use Void as response type.");
}
//找到对应的转换器
Converter<ResponseBody, ResponseT> responseConverter = createResponseConverter(retrofit, method, responseType);
okhttp3.Call.Factory callFactory = retrofit.callFactory;
//创建支持适配工作的HttpServiceMethod,就是复写adapt()方法,并使用适配器进行转换
return new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter);
}
/**
* 找到支持适配返回值类型的CallAdapter
*/
private static <ResponseT, ReturnT> CallAdapter<ResponseT, ReturnT> createCallAdapter(
Retrofit retrofit, Method method, Type returnType, Annotation[] annotations) {
try {
//noinspection unchecked
return (CallAdapter<ResponseT, ReturnT>) retrofit.callAdapter(returnType, annotations);
} catch (RuntimeException e) { // Wide exception range because factories are user code.
throw methodError(method, e, "Unable to create call adapter for %s", returnType);
}
}
/**
* 找到对应的转换器
*/
private static <ResponseT> Converter<ResponseBody, ResponseT> createResponseConverter(
Retrofit retrofit, Method method, Type responseType) {
Annotation[] annotations = method.getAnnotations();
try {
return retrofit.responseBodyConverter(responseType, annotations);
} catch (RuntimeException e) { // Wide exception range because factories are user code.
throw methodError(method, e, "Unable to create converter for %s", responseType);
}
}
/**
* 执行方法调用
*/
@Override
final @Nullable
ReturnT invoke(Object[] args) {
//创建Call实例
Call<ResponseT> call = new OkHttpCall<>(requestFactory, args, callFactory, responseConverter);
//进行适配后返回结果
return adapt(call, args);
}
/**
* 适配方法
*/
protected abstract @Nullable
ReturnT adapt(Call<ResponseT> call, Object[] args);
/**
* 支持进行适配的HttpServiceMethod子类
*/
static final class CallAdapted<ResponseT, ReturnT> extends HttpServiceMethod<ResponseT, ReturnT> {
private final CallAdapter<ResponseT, ReturnT> callAdapter;
CallAdapted(
RequestFactory requestFactory,
okhttp3.Call.Factory callFactory,
Converter<ResponseBody, ResponseT> responseConverter,
CallAdapter<ResponseT, ReturnT> callAdapter) {
super(requestFactory, callFactory, responseConverter);
this.callAdapter = callAdapter;
}
@Override
protected ReturnT adapt(Call<ResponseT> call, Object[] args) {
//使用CallAdapter适配请求的返回值
return callAdapter.adapt(call);
}
}
}
CallAdapter适配器
- createCallAdapter,查找适配器
查找适配器的工作,发现是通过Retrofit
实例callAdapter()
方法,for循环查找注册的适配器,如果没有找到则抛异常,这实际上是策略模式的应用
public final class Retrofit {
/**
* 返回可以适配返回值类型的CallAdapter实例
*
* @throws IllegalArgumentException 如果没有找到,抛出异常
*/
public CallAdapter<?, ?> callAdapter(Type returnType, Annotation[] annotations) {
return nextCallAdapter(null, returnType, annotations);
}
/**
* 返回可以适配返回值类型的CallAdapter实例
*
* @throws IllegalArgumentException 如果没有找到,抛出异常
*/
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) {
return adapter;
}
}
StringBuilder builder =
new StringBuilder("Could not locate call adapter for ").append(returnType).append(".\n");
if (skipPast != null) {
builder.append(" Skipped:");
for (int i = 0; i < start; i++) {
builder.append("\n * ").append(callAdapterFactories.get(i).getClass().getName());
}
builder.append('\n');
}
builder.append(" Tried:");
for (int i = start, count = callAdapterFactories.size(); i < count; i++) {
builder.append("\n * ").append(callAdapterFactories.get(i).getClass().getName());
}
throw new IllegalArgumentException(builder.toString());
}
}
- CallAdapter和CallAdapter.Factory
CallAdapter.Factory
是CallAdapter
的工厂类,每次发起请求,都是通过CallAdapter.Factory
创建一个CallAdapter
进行适配工作
主要方法是Factory.get()
,创建CallAdapter
,而CallAdapter
的主要方法是adapt
,该方法对Call类进行适配,以及responseType()
,该方法返回该适配器能处理的返回值类型中的泛型Type
在Retrofit
构建时,就添加了一个默认的CallAdapter.Factory
实例,它就是DefaultCallAdapterFactory
,所以就是我们什么都不配置,默认找到的CallAdapter.Factory
就是DefaultCallAdapterFactory
/**
* 适配器,把Call中的泛型适配为返回值中的泛型
*/
public interface CallAdapter<R, T> {
/**
* 获取适配后的类型,例如{@code Call<Repo>},返回的是Repo的Type对象
*/
Type responseType();
/**
* 把Call<R>适配为对应的返回值类型的泛型
*/
T adapt(Call<R> call);
/**
* CallAdapter工厂,每次请求都会通过这个工厂生产CallAdapter
*/
abstract class Factory {
/**
* 对方法进行适配,如果适配不了,返回null
*/
public abstract @Nullable
CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit);
/**
* 获取泛型的上界类型,例如{@Code Map<String, ? extends Runnable>},会返回Runnable
*/
protected static Type getParameterUpperBound(int index, ParameterizedType type) {
return Utils.getParameterUpperBound(index, type);
}
/**
* 获取原始类型,例如{@code List<? extends Runnable>},会返回List
*/
protected static Class<?> getRawType(Type type) {
return Utils.getRawType(type);
}
}
}
- DefaultCallAdapterFactory,默认的CallAdapter工厂
发现这个工厂类,在get()
方法中,创建了一个CallAdapter
的匿名内部类,responseType()
返回了Call中的泛型Type,然后adapt()
方法创建了一个ExecutorCallbackCall
类,该类实现了Call
接口
它其实是一个装饰器,包装了当前请求的Call
类实例,并把enqueue()
方法中的回调通过callbackExecutor
做了调用包装,这个callbackExecutor
就是Platform
类中的MainThreadExecutor
实例,所以就是这里来做回调的主线程回调的!
/**
* 默认的CallAdapter工厂
*/
final class DefaultCallAdapterFactory extends CallAdapter.Factory {
/**
* 回调执行器
*/
private final @Nullable
Executor callbackExecutor;
DefaultCallAdapterFactory(@Nullable Executor callbackExecutor) {
this.callbackExecutor = callbackExecutor;
}
@Override
public @Nullable
CallAdapter<?, ?> get(
Type returnType, Annotation[] annotations, Retrofit retrofit) {
//返回值类型不是Call类型,不处理
if (getRawType(returnType) != Call.class) {
return null;
}
//返回值类型必须有泛型,或带上界的泛型
if (!(returnType instanceof ParameterizedType)) {
throw new IllegalArgumentException(
"Call return type must be parameterized as Call<Foo> or Call<? extends Foo>");
}
//获取Call中的泛型
final Type responseType = Utils.getParameterUpperBound(0, (ParameterizedType) returnType);
//是否添加了SkipCallbackExecutor注解,如果添加了该注解,会不使用配置的callbackExecutor进行回调
final Executor executor =
Utils.isAnnotationPresent(annotations, SkipCallbackExecutor.class)
? null
: callbackExecutor;
//创建一个CallAdapter,把数据原封不动返回
return new CallAdapter<Object, Call<?>>() {
@Override
public Type responseType() {
return responseType;
}
@Override
public Call<Object> adapt(Call<Object> call) {
return executor == null ? call : new ExecutorCallbackCall<>(executor, call);
}
};
}
/**
* 装饰器,带回调执行器的Call,因为在OkHttpCall中的回调都是子线程回调的,这里可以再转到主线程进行回调
*/
static final class ExecutorCallbackCall<T> implements Call<T> {
final Executor callbackExecutor;
final Call<T> delegate;
ExecutorCallbackCall(Executor callbackExecutor, Call<T> delegate) {
this.callbackExecutor = callbackExecutor;
this.delegate = delegate;
}
@Override
public void enqueue(final Callback<T> callback) {
Objects.requireNonNull(callback, "callback == null");
delegate.enqueue(new Callback<T>() {
@Override
public void onResponse(Call<T> call, final Response<T> response) {
callbackExecutor.execute(
() -> {
if (delegate.isCanceled()) {
// Emulate OkHttp's behavior of throwing/delivering an IOException on
// cancellation.
callback.onFailure(ExecutorCallbackCall.this, new IOException("Canceled"));
} else {
callback.onResponse(ExecutorCallbackCall.this, response);
}
});
}
@Override
public void onFailure(Call<T> call, final Throwable t) {
callbackExecutor.execute(() -> callback.onFailure(ExecutorCallbackCall.this, t));
}
});
}
@Override
public boolean isExecuted() {
return delegate.isExecuted();
}
@Override
public Response<T> execute() throws IOException {
return delegate.execute();
}
@Override
public void cancel() {
delegate.cancel();
}
@Override
public boolean isCanceled() {
return delegate.isCanceled();
}
@SuppressWarnings("CloneDoesntCallSuperClone") // Performing deep clone.
@Override
public Call<T> clone() {
return new ExecutorCallbackCall<>(callbackExecutor, delegate.clone());
}
@Override
public Request request() {
return delegate.request();
}
@Override
public Timeout timeout() {
return delegate.timeout();
}
}
}
Converter转换器
CallAdapter
查找完后,再查找Converter
转换器,它的逻辑和上面查找CallAdapter
很类似,都是在Retrofit
的实例上找,Converter
也有一个Factory
工厂类
public final class Retrofit {
/**
* 获取支持返回值中的泛型为ResponseBody的Converter转换器
*/
public <T> Converter<ResponseBody, T> responseBodyConverter(Type type, Annotation[] annotations) {
return nextResponseBodyConverter(null, type, annotations);
}
/**
* 获取支持返回值中的泛型为ResponseBody的Converter转换器
*
* @param skipPast 可以指定跳过某个转换器
*/
public <T> Converter<ResponseBody, T> nextResponseBodyConverter(
@Nullable Converter.Factory skipPast, Type type, Annotation[] annotations) {
Objects.requireNonNull(type, "type == null");
Objects.requireNonNull(annotations, "annotations == null");
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;
}
}
StringBuilder builder =
new StringBuilder("Could not locate ResponseBody converter for ")
.append(type)
.append(".\n");
if (skipPast != null) {
builder.append(" Skipped:");
for (int i = 0; i < start; i++) {
builder.append("\n * ").append(converterFactories.get(i).getClass().getName());
}
builder.append('\n');
}
builder.append(" Tried:");
for (int i = start, count = converterFactories.size(); i < count; i++) {
builder.append("\n * ").append(converterFactories.get(i).getClass().getName());
}
throw new IllegalArgumentException(builder.toString());
}
}
- Converter.Factory,转换器工厂
同样,每次请求则创建都通过Factory
创建一个Converter
实例,Converter
有2种
responseBodyConverter()
,把ResponseBody转换为Type类型的模型(请求响应回来时调用),就是负责把接口响应的json数据,转换为对应的模型类
requestBodyConverter()
,把Type模型转换为RequestBody,就是application/json这种类型的请求,把模型类转换为Json字符串,然后把Json字符串设置到RequestBody中
public interface Converter<F, T> {
/**
* 转换方法
*/
@Nullable
T convert(F value) throws IOException;
/**
* Converter转换器的工厂
*/
abstract class Factory {
/**
* 把ResponseBody转换为Type类型的模型(请求响应回来时调用)
*/
public @Nullable
Converter<ResponseBody, ?> responseBodyConverter(
Type type, Annotation[] annotations, Retrofit retrofit) {
return null;
}
/**
* 把Type模型转换为RequestBody(application/json请求前调用)
*/
public @Nullable
Converter<?, RequestBody> requestBodyConverter(
Type type,
Annotation[] parameterAnnotations,
Annotation[] methodAnnotations,
Retrofit retrofit) {
return null;
}
/**
* 把RequestBody转换为String类型的Converter
*/
public @Nullable
Converter<?, String> stringConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
return null;
}
/**
* 获取泛型的上界类型,例如{@Code Map<String, ? extends Runnable>},会返回Runnable
*/
protected static Type getParameterUpperBound(int index, ParameterizedType type) {
return Utils.getParameterUpperBound(index, type);
}
/**
* 获取原始类型,例如{@code List<? extends Runnable>},会返回List
*/
protected static Class<?> getRawType(Type type) {
return Utils.getRawType(type);
}
}
}
- BuiltInConverters,默认的转换器工厂
在Retrofit实例
创建中,也默认添加了一个转换器工厂,它就是BuiltInConverters
/**
* 默认的Converter转换器工厂
*/
final class BuiltInConverters extends Converter.Factory {
@Override
public @Nullable
Converter<ResponseBody, ?> responseBodyConverter(
Type type, Annotation[] annotations, Retrofit retrofit) {
//方法的返回值中的泛型,是ResponseBody时才可以使用
if (type == ResponseBody.class) {
return Utils.isAnnotationPresent(annotations, Streaming.class)
? StreamingResponseBodyConverter.INSTANCE
: BufferingResponseBodyConverter.INSTANCE;
}
//泛型为Void
if (type == Void.class) {
return VoidResponseBodyConverter.INSTANCE;
}
return null;
}
@Override
public @Nullable
Converter<?, RequestBody> requestBodyConverter(
Type type,
Annotation[] parameterAnnotations,
Annotation[] methodAnnotations,
Retrofit retrofit) {
//方法的形参有RequestBody时使用
if (RequestBody.class.isAssignableFrom(Utils.getRawType(type))) {
return RequestBodyConverter.INSTANCE;
}
return null;
}
/**
* 返回值的泛型是Void时使用
*/
static final class VoidResponseBodyConverter implements Converter<ResponseBody, Void> {
static final VoidResponseBodyConverter INSTANCE = new VoidResponseBodyConverter();
@Override
public Void convert(ResponseBody value) {
value.close();
return null;
}
}
/**
* RequestBody转换器
*/
static final class RequestBodyConverter implements Converter<RequestBody, RequestBody> {
static final RequestBodyConverter INSTANCE = new RequestBodyConverter();
@Override
public RequestBody convert(RequestBody value) {
//原封不动返回
return value;
}
}
static final class StreamingResponseBodyConverter
implements Converter<ResponseBody, ResponseBody> {
static final StreamingResponseBodyConverter INSTANCE = new StreamingResponseBodyConverter();
@Override
public ResponseBody convert(ResponseBody value) {
return value;
}
}
static final class BufferingResponseBodyConverter
implements Converter<ResponseBody, ResponseBody> {
static final BufferingResponseBodyConverter INSTANCE = new BufferingResponseBodyConverter();
@Override
public ResponseBody convert(ResponseBody value) throws IOException {
try {
// Buffer the entire body to avoid future I/O.
return Utils.buffer(value);
} finally {
value.close();
}
}
}
/**
* 返回值的泛型是String
*/
static final class ToStringConverter implements Converter<Object, String> {
static final ToStringConverter INSTANCE = new ToStringConverter();
@Override
public String convert(Object value) {
return value.toString();
}
}
}
Call,发起请求
通过上面的步骤,解析API接口上的注解,查找CallAdapter
和Converter
,只是loadServiceMethod()
的处理过程,然后返回ServiceMethod
实例,再调用它的invoke()
方法进行调用,而ServiceMethod
只是抽象类,具体实现在HttpServiceMethod
invoke()
,返回一个Call
实例,而它是一个接口,提供了一些请求方法,核心实现是OkHttpCall
,还有一个ExecutorCallbackCall
子类是做装饰器作用的,主要把回调方法通过平台的主线程调度器进行转发,实现主线程回调
abstract class HttpServiceMethod<ResponseT, ReturnT> extends ServiceMethod<ReturnT> {
/**
* 执行方法调用
*/
@Override
final @Nullable
ReturnT invoke(Object[] args) {
//创建Call实例
Call<ResponseT> call = new OkHttpCall<>(requestFactory, args, callFactory, responseConverter);
//进行适配后返回结果
return adapt(call, args);
}
}
- Call接口
主要请求方法有2个,execute
同步请求,enqueue
异步请求
/**
* 请求封装,内部封装了OkHttp的Call
*/
public interface Call<T> extends Cloneable {
/**
* 同步请求
*/
Response<T> execute() throws IOException;
/**
* 异步请求
*
* @param callback 回调
*/
void enqueue(Callback<T> callback);
/**
* 是否已经被执行
*/
boolean isExecuted();
/**
* 取消请求
*/
void cancel();
/**
* 是否请求已经被取消
*/
boolean isCanceled();
/**
* 克隆请求
*/
Call<T> clone();
/**
* 获取请求的Request对象
*/
Request request();
/**
* 获取请求的超时配置
*/
Timeout timeout();
}
- OkHttpCall
发现,OkHttpCall
是对OkHttp的一层封装,做了一些响应码的处理,和Convert
转换器的调用,OkHttp
的Call
类是没有数据转换的,而Retrofit的Call
类则是有Convert
的支持,实现数据和模型的转换
/**
* Call接口的实现,使用OkHttp进行请求,并进行结果回调的封装类,具有数据和模型的转换能力
*/
final class OkHttpCall<T> implements Call<T> {
private final RequestFactory requestFactory;
private final Object[] args;
private final okhttp3.Call.Factory callFactory;
private final Converter<ResponseBody, T> responseConverter;
private volatile boolean canceled;
@GuardedBy("this")
private @Nullable
okhttp3.Call rawCall;
@GuardedBy("this") // Either a RuntimeException, non-fatal Error, or IOException.
private @Nullable
Throwable creationFailure;
@GuardedBy("this")
private boolean executed;
OkHttpCall(
RequestFactory requestFactory,
Object[] args,
okhttp3.Call.Factory callFactory,
Converter<ResponseBody, T> responseConverter) {
this.requestFactory = requestFactory;
this.args = args;
this.callFactory = callFactory;
this.responseConverter = responseConverter;
}
@SuppressWarnings("CloneDoesntCallSuperClone") // We are a final type & this saves clearing state.
@Override
public OkHttpCall<T> clone() {
return new OkHttpCall<>(requestFactory, args, callFactory, responseConverter);
}
@Override
public synchronized Request request() {
try {
return getRawCall().request();
} catch (IOException e) {
throw new RuntimeException("Unable to create request.", e);
}
}
@Override
public synchronized Timeout timeout() {
try {
return getRawCall().timeout();
} catch (IOException e) {
throw new RuntimeException("Unable to create call.", e);
}
}
/**
* 获取真实请求的实例,就是OkHttp的Call
*/
@GuardedBy("this")
private okhttp3.Call getRawCall() throws IOException {
okhttp3.Call call = rawCall;
//已经生成过了,直接返回
if (call != null) {
return call;
}
//不是第一次进行接口请求,并且发生错误,把错误再次抛出
if (creationFailure != null) {
if (creationFailure instanceof IOException) {
throw (IOException) creationFailure;
} else if (creationFailure instanceof RuntimeException) {
throw (RuntimeException) creationFailure;
} else {
throw (Error) creationFailure;
}
}
//创建OkHttp的Call对象
try {
return rawCall = createRawCall();
} catch (RuntimeException | Error | IOException e) {
throwIfFatal(e); // Do not assign a fatal error to creationFailure.
creationFailure = e;
throw e;
}
}
@Override
public void enqueue(final Callback<T> callback) {
Objects.requireNonNull(callback, "callback == null");
okhttp3.Call call;
Throwable failure;
synchronized (this) {
//调用了一次enqueue()异步请求,不能再次调用
if (executed) throw new IllegalStateException("Already executed.");
executed = true;
call = rawCall;
failure = creationFailure;
//创建OkHttp的Call对象
if (call == null && failure == null) {
try {
call = rawCall = createRawCall();
} catch (Throwable t) {
throwIfFatal(t);
failure = creationFailure = t;
}
}
}
//失败了,回调外部
if (failure != null) {
callback.onFailure(this, failure);
return;
}
//取消了任务,对真实请求做取消
if (canceled) {
call.cancel();
}
//发起异步请求
call.enqueue(new okhttp3.Callback() {
@Override
public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse) {
Response<T> response;
try {
//执行,并解析响应,统一返回Retrofit的Response对象
response = parseResponse(rawResponse);
} catch (Throwable e) {
//解析失败,回调外部
throwIfFatal(e);
callFailure(e);
return;
}
//解析成功,回调外部
try {
callback.onResponse(OkHttpCall.this, response);
} catch (Throwable t) {
throwIfFatal(t);
t.printStackTrace(); // TODO this is not great
}
}
@Override
public void onFailure(okhttp3.Call call, IOException e) {
//请求失败,回调外部
callFailure(e);
}
/**
* 回调失败
*/
private void callFailure(Throwable e) {
try {
callback.onFailure(OkHttpCall.this, e);
} catch (Throwable t) {
throwIfFatal(t);
t.printStackTrace(); // TODO this is not great
}
}
});
}
@Override
public synchronized boolean isExecuted() {
return executed;
}
@Override
public Response<T> execute() throws IOException {
okhttp3.Call call;
//同步请求
synchronized (this) {
if (executed) throw new IllegalStateException("Already executed.");
executed = true;
call = getRawCall();
}
//如果被取消,则取消任务
if (canceled) {
call.cancel();
}
//执行,并解析响应,统一返回Retrofit的Response对象
return parseResponse(call.execute());
}
/**
* 创建OkHttp3的Call对象
*/
private okhttp3.Call createRawCall() throws IOException {
okhttp3.Call call = callFactory.newCall(requestFactory.create(args));
//设置的OkHttpClient,不能返回null
if (call == null) {
throw new NullPointerException("Call.Factory returned null.");
}
return call;
}
/**
* 执行,并解析响应,统一返回Retrofit的Response对象
*/
Response<T> parseResponse(okhttp3.Response rawResponse) throws IOException {
ResponseBody rawBody = rawResponse.body();
//移除真实请求的Body,方便传递
rawResponse = rawResponse
.newBuilder()
.body(new NoContentResponseBody(rawBody.contentType(), rawBody.contentLength()))
.build();
int code = rawResponse.code();
//响应码不为正常的
if (code < 200 || code >= 300) {
try {
ResponseBody bufferedBody = Utils.buffer(rawBody);
//生成错误的Response对象
return Response.error(bufferedBody, rawResponse);
} finally {
//关闭流
rawBody.close();
}
}
//204:请求成功了,但是没有相应体
//205:请求成功了,重置表单,一般WebView才有
if (code == 204 || code == 205) {
rawBody.close();
//由于没有响应体,直接返回成功
return Response.success(null, rawResponse);
}
//包装一层,捕获异常
ExceptionCatchingResponseBody catchingBody = new ExceptionCatchingResponseBody(rawBody);
try {
//把ResponseBody转换具体的泛型模型类
T body = responseConverter.convert(catchingBody);
//返回Response
return Response.success(body, rawResponse);
} catch (RuntimeException e) {
// If the underlying source threw an exception, propagate that rather than indicating it was
// a runtime exception.
catchingBody.throwIfCaught();
throw e;
}
}
@Override
public void cancel() {
canceled = true;
okhttp3.Call call;
synchronized (this) {
call = rawCall;
}
//取消任务
if (call != null) {
call.cancel();
}
}
@Override
public boolean isCanceled() {
if (canceled) {
return true;
}
synchronized (this) {
return rawCall != null && rawCall.isCanceled();
}
}
static final class NoContentResponseBody extends ResponseBody {
private final @Nullable
MediaType contentType;
private final long contentLength;
NoContentResponseBody(@Nullable MediaType contentType, long contentLength) {
this.contentType = contentType;
this.contentLength = contentLength;
}
@Override
public MediaType contentType() {
return contentType;
}
@Override
public long contentLength() {
return contentLength;
}
@Override
public BufferedSource source() {
throw new IllegalStateException("Cannot read raw response body of a converted body.");
}
}
/**
* 装饰器,捕获异常的ResponseBody
*/
static final class ExceptionCatchingResponseBody extends ResponseBody {
private final ResponseBody delegate;
private final BufferedSource delegateSource;
@Nullable
IOException thrownException;
ExceptionCatchingResponseBody(ResponseBody delegate) {
this.delegate = delegate;
this.delegateSource = Okio.buffer(
new ForwardingSource(delegate.source()) {
@Override
public long read(Buffer sink, long byteCount) throws IOException {
try {
return super.read(sink, byteCount);
} catch (IOException e) {
thrownException = e;
throw e;
}
}
});
}
@Override
public MediaType contentType() {
return delegate.contentType();
}
@Override
public long contentLength() {
return delegate.contentLength();
}
@Override
public BufferedSource source() {
return delegateSource;
}
@Override
public void close() {
delegate.close();
}
void throwIfCaught() throws IOException {
if (thrownException != null) {
throw thrownException;
}
}
}
}
Gson转换器
Converter
转换器主要是做2种事情
- Json上传类型的请求时,模型转Json
- 接口响应时,Json转模型
而Gson就拥有这样的能力,所以Retrofit
也提供Gson
的转换器工厂,GsonConverterFactory
简单使用
在Retrofit.Builder
构建时,通过addConverterFactory
,添加GsonConverterFactory
转换器
//创建Retrofit实例
Retrofit retrofit = new Retrofit.Builder()
//配置OkHttpClient
.callFactory(new OkHttpClient.Builder().build())
//配置基础Url
.baseUrl("https://www.wanandroid.com")
//Gson转换器
.addConverterFactory(GsonConverterFactory.create())
//开始创建
.build();
- 添加一个请求方法,可以直接写模型的泛型
public interface WanAndroid {
/**
* Retrofit Call,获取首页文章列表,如果不添加转换器,则泛型只能是ResponseBody
*/
@GET("article/list/{page}/json")
Call<ResponseBody> getHomeArticleByCall(@Path("page") int page);
/**
* 添加了转换器,则可以直接用模型类的泛型,不需要ResponseBody了
*/
@GET("article/list/{page}/json")
Call<HttpModel<PageModel<HomeArticleModel>>> getHomeArticleByCallWithConverter(
@Path("page") int page
);
}
- 调用,不需要自己做Json和模型的转换,优雅了许多
wanAndroid.getHomeArticleByCallWithConverter(page).enqueue(new Callback<HttpModel<PageModel<HomeArticleModel>>>() {
@Override
public void onResponse(Call<HttpModel<PageModel<HomeArticleModel>>> call,
Response<HttpModel<PageModel<HomeArticleModel>>> response) {
//请求成功
}
@Override
public void onFailure(Call<HttpModel<PageModel<HomeArticleModel>>> call, Throwable throwable) {
//请求失败
}
});
源码分析
- 转换器工厂,实现Converter.Factory接口
/**
* Gson转换器工厂
*/
public final class GsonConverterFactory extends Converter.Factory {
/**
* 创建方法,使用默认构造方法的Gson实例,JSON解码使用UTF-8
*/
public static GsonConverterFactory create() {
return create(new Gson());
}
/**
* 指定Gson实例进行创建
*/
@SuppressWarnings("ConstantConditions") // Guarding public API nullability.
public static GsonConverterFactory create(Gson gson) {
if (gson == null) throw new NullPointerException("gson == null");
return new GsonConverterFactory(gson);
}
private final Gson gson;
private GsonConverterFactory(Gson gson) {
this.gson = gson;
}
@Override
public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations,
Retrofit retrofit) {
//ResponseBody响应数据转模型
TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
return new GsonResponseBodyConverter<>(gson, adapter);
}
@Override
public Converter<?, RequestBody> requestBodyConverter(Type type,
Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
//Json请求方式时,模型转Json
TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
return new GsonRequestBodyConverter<>(gson, adapter);
}
}
- GsonRequestBodyConverter,Json请求方式时,模型转Json的转换器
/**
* Json请求方式时,模型转Json的转换器
*/
final class GsonRequestBodyConverter<T> implements Converter<T, RequestBody> {
private static final MediaType MEDIA_TYPE = MediaType.get("application/json; charset=UTF-8");
private static final Charset UTF_8 = Charset.forName("UTF-8");
private final Gson gson;
private final TypeAdapter<T> adapter;
GsonRequestBodyConverter(Gson gson, TypeAdapter<T> adapter) {
this.gson = gson;
this.adapter = adapter;
}
@Override public RequestBody convert(T value) throws IOException {
Buffer buffer = new Buffer();
Writer writer = new OutputStreamWriter(buffer.outputStream(), UTF_8);
JsonWriter jsonWriter = gson.newJsonWriter(writer);
adapter.write(jsonWriter, value);
jsonWriter.close();
return RequestBody.create(MEDIA_TYPE, buffer.readByteString());
}
}
- GsonResponseBodyConverter,ResponseBody响应数据转模型的转换器
/**
* ResponseBody响应数据转模型的转换器
*/
final class GsonResponseBodyConverter<T> implements Converter<ResponseBody, T> {
private final Gson gson;
private final TypeAdapter<T> adapter;
GsonResponseBodyConverter(Gson gson, TypeAdapter<T> adapter) {
this.gson = gson;
this.adapter = adapter;
}
@Override public T convert(ResponseBody value) throws IOException {
JsonReader jsonReader = gson.newJsonReader(value.charStream());
try {
T result = adapter.read(jsonReader);
if (jsonReader.peek() != JsonToken.END_DOCUMENT) {
throw new JsonIOException("JSON document was not fully consumed.");
}
return result;
} finally {
value.close();
}
}
}
总结
Retrofit中,使用了很多设计模式,例如:
- 创建实例时使用Builder构建者模式,配置更加灵活
- 代理模式,主要是JDK动态代理,让我们可以用接口,实现声明式Http请求调用
- 责任链模式,配置多个CallAdapter和Converter,查找到最终匹配当前调用的方法的返回值,和Json和模型之间转换
- 策略模式,不同平台的主线程执行器实现,通过Platform类拓展不同平台的子类
- 装饰器模式,ExecutorCallbackCall,实现Call接口,对同样实现了Call接口的OkHttpCall进行装饰,实现enqueue()异步请求的回调在主线程中回调
既然Retrofit可以兼容多平台,而鸿蒙系统,也是基于Java,同样有主线程API,我们是不是可以拓展Retrofit的Platform类,实现鸿蒙上的子线程请求,主线程回调呢~