参考文档:
Retrofit 版本号:2.9.0
Retrofit简单来说,就是对OkHttp上层进行了封装,已达到用户方便使用管理网络请求的目的。
Retrofit内部有着简捷、优雅的结构设计。当然对于新手来说,Retrofit也有着不宜理解和上手的问题。不过瑕不掩瑜,Retrofit仍然是一款优秀的网络请求框架。
这边文章除了进行源码分析,还有个人对Retrofit的一些浅见和感悟。仅供读者参考。
一.使用方法
早期网络请求方式,一般都是设计一个OKHttpUtil之类的工具类,实现对Okhttp请求的封装,入参传入url、请求参数param,回调函数callback。这样的请求方式对新用户来说是非常易于上手和容易理解的,但为什么还要使用Retrofit呢,它到底能给我们带来什么呢?
先看看使用方法吧:
使用示例中的接口来自www.wanandroid.com/
1.添加Retrofit依赖
scss
implementation("com.squareup.retrofit2:retrofit:2.9.0")
// retrofit gson转换器
implementation("com.squareup.retrofit2:converter-gson:2.9.0")
2.创建一个接口
用于管理不同的网络请求
这里第一个接口返回的类型为Call,此处的Call为Retrofit中的接口,并非Okhttp中的Call(虽然他们接口中定义的方法很类似),如果不特别说明,后面源码分析中的也是这个Call。
less
interface MainService {
@GET("article/list/{index}/json")
fun paperList(@Path("index") index: Int): Call<MainPaperList>
@GET("hotkey/json")
suspend fun hotkey(): HotKey
@POST("hotkey/json")
suspend fun hotkey2(@Body req: TestReq): HotKey
}
3.创建Retrofit并创建接口实现的实例
创建Retrofit,完成配置。
这里的接口实现使用Java动态代理方式。
scss
// 1.Retrofit创建
val retrofit = Retrofit
.Builder()
.baseUrl("https://www.wanandroid.com/")
.addConverterFactory(GsonConverterFactory.create())
.build()
// 2.创建网络请求接口示例
val service = retrofit.create(MainService::class.java)
4.发起请求
这里给出异步请求的示例,默认情况下回调函数会在主线程运行。
动态代理实现中,对调用接口方法进行解析,包括接口参数、返回值和注解,根据这些配置项使用OKHttp进行网络请求。
这里使用反射方式进行解析,可能会稍有耗时,但解析完成后会放在缓存中,再次请求时从缓存中取用。
kotlin
fun queryPaperList() {
service.paperList(0)
.enqueue(object : Callback<MainPaperList> {
override fun onResponse(
call: Call<MainPaperList>,
response: Response<MainPaperList>
) {
// 请求成功
}
override fun onFailure(call: Call<MainPaperList>, t: Throwable) {
// 请求异常
}
})
}
5.推荐个IDEA插件
在IDEA插件搜索框搜索Retrofit就可以出来。
1.RestfulTool Retrofit
这个插件可以浏览并快速定位到自己定义的Retrofit接口。免费使用。
2.Retrofit Assistant
这个插件功能强大,方便用户快速创建和浏览网络请求的定义的接口,有30天免费试用期,之后使用需要付费。
可以参考插件作者的这篇文章了解:juejin.cn/post/729416...
二.为什么好用
Retrofit有以下优点,分开来解读
1.写法简洁
用接口进行网络请求管理对于初学者来说确实比较怪异,有一定学习曲线,需要花时间来熟悉用法和实现原理。但这样的写法非常简洁方便,声明式的方式定义和处理网络请求可以减少了样板代码的编写。
2.主流支持
同时Retrofit内部实现了对RxJava和协程(2.6.0版本之后)的支持,以及对Json、xml数据格式的支持。这些支持方式免去了使用者去费劲编写转换代码。
3.可扩展
如果需要对请求数据和返回数据做一些转换或者特殊处理,Retrofit同样提供了入口允许用户进行一些特殊处理,比如设置自己的okhttpClient;如需对请求数据和返回数据做一些转换或者特殊处理,可以设置自定义的converterFactory;还可以配置callAdapterFactory,实现特殊的请求方式。
Retrofit存在着大量的设计模式,这些设计模式实现了代码的解耦课可拓展性,这里配置中出现converterFactory和callAdapterFactory都是工厂方法模式的使用。有一些经验的开发者觉得阅读起来会觉得很舒服,而初学者则会有一定的阅读困难。不过很多设计模式都会有这样的问题。设计模式已经广泛应用在各个开源组件的代码中,学习和使用设计模式是提高代码理解能力的必备功课吧。
三.结构总览
Retrofit经营着一家高档餐厅,餐厅里共有五个部门。第一个部门是主厨部门,一个主厨只负责一道菜的指挥和监督工作。还有四个部门,分别归四个管家管理,每个管家负责对小厨娘进行招募,每个部门的小厨娘只负责做菜的其中一个环节。
当一道菜品需要制作时,会组建一个厨师团队进行菜品制作的部署工作,这个团队安排一个主厨负责,还有几个小厨娘供主厨指挥,在部署工作进行中还会招募一些其他帮手。
几个个小厨娘各司其职,互相配合,在主厨指挥下,完成任务,厨师负责最后摆盘,供客人食用。
四个 管家:callFactory、converterFactories、callAdapterFactories、callbackExecutor
主厨团队:serviceMethodCache
请记住这四个管家,他们将在后面源码中频繁出现。
四.源码分析
源码中关键地方都做了中文注释
1.人员预备:Retrofit和Retrofit.Build
这里主要做基础的建设工作。
Retrofit使用建造者模式创建:
ini
val retrofit = Retrofit
.Builder()
...
.build()
先看看Retrofit的内部的成员变量和构造方法:
kotlin
public final class Retrofit {
// 接口缓存。一个接口请求的方法为一个Method,对应一个ServiceMethod,ServiceMethod内部有着网络请求相关配置
private final Map<Method, ServiceMethod<?>> serviceMethodCache = new ConcurrentHashMap<>();
// OkHttp的接口,创建Okhttp请求(Call)的工厂接口,只有一个实现类:OkHttpClient
final okhttp3.Call.Factory callFactory;
// 网络请求基地址,即host地址
final HttpUrl baseUrl;
// 将请求或者返回结果进行转换的工厂类列表,比如Retrofit提供的GsonConverterFactory提供了将出入参和Gson进行转换的Converter
final List<Converter.Factory> converterFactories;
// callAdapter工厂集合,CallAdapter就是Call的转换器(Retrofit中的Call),callAdapterFactory会根据自己的能力返回合适的CallAdapter
final List<CallAdapter.Factory> callAdapterFactories;
// Call请求的回调方法运行的executor,默认Retrofit定义的MainThreadExecutor,即运行在主线程的Executor
final @Nullable Executor callbackExecutor;
// 字面意思就是提前验证,如果是true的话,当retrofit.create创建接口实现类时,就进行接口的解析和初始化,生成相应的ServiceMethod,放入缓存map中
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;
}
}
Retrofit.Builder中的成员变量除了多了一个Platform,其他与Retrofit的那些一样,Builder里的方法也是对这些值得设置。
这里的Platform要重点说明一下
Platform提供了对Android和Java平台的支持,也就是说Retrofit不仅可以用在Android开发,还可以用于后端Java开发。
Platform具体提供了以下内容:
1.默认的CallAdapterFactory。 通过defaultCallAdapterFactories方法,其中有DefaultCallAdapterFactory(将异步请求结果的回调使用callbackExecutor运行)、CompletableFutureCallAdapterFactory.INSTANCE(将Call转换为CompletableFuture)。
2.默认的ConverterFactory。 通过defaultConverterFactories方法,只有OptionalConverterFactory.INSTANCE(将结果转换成Optional)。
3.默认的callbackExecutor。 通过defaultCallbackExecutor,这里只有Android平台会提供一个MainThreadExecutor。
我们只分析Android平台。可以认为,Platform提供了Builder进行初始化时四个管家其中三个的默认配置,即converterFactories、callAdapterFactories、callbackExecutor的默认配置(CompletableFutureCallAdapterFactory和OptionalConverterFactory基本上是用不上,此处忽略)。
看看Builder的build方法,是如何完成Retrofit的创建工作:
csharp
public Retrofit build() {
if (baseUrl == null) {
throw new IllegalStateException("Base URL required.");
}
okhttp3.Call.Factory callFactory = this.callFactory;
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);
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.
converterFactories.add(new BuiltInConverters());
converterFactories.addAll(this.converterFactories);
converterFactories.addAll(platform.defaultConverterFactories());
return new Retrofit(
callFactory,
baseUrl,
unmodifiableList(converterFactories),
unmodifiableList(callAdapterFactories),
callbackExecutor,
validateEagerly);
}
build方法非常清晰,将Platform提供的用户的配置和Platform提供的默认支持加入,完成Retrofit的创建。
如果没有设置callFactory,那么久创建一个OkHttpClient对象。BuiltInConverters提供了对接口返回值为Void、Unit的支持,以及对注解为Streaming的支持。
2.报菜员就位:Retrofit.create
这一部分是接口实例化工作。
这里分析下面这行代码的源码
ini
val service = retrofit.create(MainService::class.java)
typescript
public <T> T create(final Class<T> service) {
// 如果validateEagerly为true,这里直接对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 the method is a method from Object then defer to normal invocation.
if (method.getDeclaringClass() == Object.class) {
return method.invoke(this, args);
}
// 如果是接口默认方法,则调用默认方法,如果不是则调用loadServiceMethod(method).invoke
args = args != null ? args : emptyArgs;
return platform.isDefaultMethod(method)
? platform.invokeDefaultMethod(method, service, proxy, args)
: loadServiceMethod(method).invoke(args);
}
});
}
源码中使用了Java提供的动态代理的方式对接口进行实例化。
这里简单讲一下,当用户使用service这个对象调用接口方法时,会被分发到InvocationHandler,并调用起invoke方法,传入这个方法的method和入参args。
Method是Java反射包中的一个类,通过method,我们可以轻松获取到这个方法的注解和入参,由此便能实现将接口转换成网络请求。这是Retrofit核心,理解了这里,再使用Retrofit,便会觉得豁然开朗。
loadServiceMethod(method).invoke(args) 这句是重点,分开来分析,先loadServiceMethod,再分析invoke(ServiceMethod的方法)。
3.分配主厨:loadServiceMethod
这一步正是Retrofit偷梁换柱的动作,将注解(菜单)转化成各种对象(菜品),并分配主厨上场。
sql
ServiceMethod<?> loadServiceMethod(Method method) {
// 先从缓存中查找
ServiceMethod<?> result = serviceMethodCache.get(method);
if (result != null) return result;
synchronized (serviceMethodCache) {
result = serviceMethodCache.get(method);
if (result == null) {
result = ServiceMethod.parseAnnotations(this, method);
serviceMethodCache.put(method, result);
}
}
return result;
}
先从缓存中查找,如果没有便通过ServiceMethod.parseAnnotations(this, method)获取到ServiceMethod,放入缓存,并返回。
java
abstract class ServiceMethod<T> {
static <T> ServiceMethod<T> parseAnnotations(Retrofit retrofit, Method method) {
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);
}
if (returnType == void.class) {
throw methodError(method, "Service methods cannot return void.");
}
return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
}
abstract @Nullable T invoke(Object[] args);
}
首先创建了requestFactory,将requestFactory传递给厨师HttpServiceMethod,然后返回。
有请主厨HttpServiceMethod闪亮登场,只见他左边张小龙(requestFactory),右边赵小虎(responseConverter),前方展小昭(callFactory)。
ini
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;
}
在这里,requestFactory成为了主厨的帮手。
下面看看RequestFactory有什么能力来帮助主厨。
先来看看RequestFactory.parseAnnotations方法和RequestFactory有哪些成员变量:
java
final class RequestFactory {
static RequestFactory parseAnnotations(Retrofit retrofit, Method method) {
return new Builder(retrofit, method).build();
}
private final Method method;
private final HttpUrl baseUrl;
final String httpMethod;
// 相对url,例如注解@GET后面的值
private final @Nullable String relativeUrl;
// 注解Headers解析,格式为 Name: Value
private final @Nullable Headers headers;
// 注解Header中Content-Type的值
private final @Nullable MediaType contentType;
// 是否有body
private final boolean hasBody;
// 是否是FormEncoded
private final boolean isFormEncoded;
// 是否是Multipart
private final boolean isMultipart;
// 方法的每个入参都有一个对应的parameterHandlers
private final ParameterHandler<?>[] parameterHandlers;
// 是否是kotlin的suspend方法
final boolean isKotlinSuspendFunction;
// 省略以下内容
}
RequestFactory依旧是工厂,但不是抽象工厂,这个工厂是Request工厂,就是创建用来创建okhttp3.Request的工厂。除了创建Request,这里对方法的注解、入参、入参注解进行了解析。
ini
Builder(Retrofit retrofit, Method method) {
this.retrofit = retrofit;
this.method = method;
// 获取方法注解,返回值为Annotation[]
this.methodAnnotations = method.getAnnotations();
// 获取方法参数类型,返回值为Type[]
this.parameterTypes = method.getGenericParameterTypes();
// 获取参数中的注解,返回值为Annotation[][]
this.parameterAnnotationsArray = method.getParameterAnnotations();
}
这里的parseAnnotations,依旧是建造者模式来创建。
Builder.build方法对RequestFactory进行创建:
ini
RequestFactory build() {
// 解析方法注解,例如GET、POST、HTTP、Multipart、FormUrlEncoded等等
for (Annotation annotation : methodAnnotations) {
parseMethodAnnotation(annotation);
}
// 略过错误检查代码...
// 解析每个入参和其注解,生成对应的ParameterHandler
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], p == lastParameter);
}
// 略过错误检查代码...
return new RequestFactory(this);
}
说一下这里的ParameterHandler,下方是ParameterHandler的源码,这是是一个用于处理请求参数的抽象类,内部只有一个抽象方法apply。在后面创建Request请求时(RequestBuilder),按顺序执行ParameterHandler列表中每个ParameterHandler的apply方法,对RequestBuilder进行处理。这又是一个巧妙使用设计模式的地方,这里用到责任链模式和策略模式。
less
abstract class ParameterHandler<T> {
abstract void apply(RequestBuilder builder, @Nullable T value) throws IOException;
// 忽略其他
}
责任链模式:ParameterHandler的实现类可以形成一个责任链,每个处理器负责处理特定类型的参数,如果当前处理器无法处理参数,则将参数传递给下一个处理器。这样可以很好地组织和管理参数的处理流程。
策略模式:ParameterHandler可以根据不同的参数类型采用不同的处理策略,每个实现类都代表一种具体的处理策略,通过接口的多态性可以灵活地切换处理策略。
这种设计模式使得Retrofit可以动态地处理各种类型的请求参数,并且方便扩展和维护。
RequestFactory源码中可以看到久违的Retrofit的注解,这里开始完成对注解和参数的解析。如果对这些注解处理感兴趣,可以看这个类。
我们再来分析分析HttpServiceMethod的parseAnnotations方法。
HttpServiceMethod的parseAnnotations方法,从名字可以看出,仍然是对注解的解析
ini
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 {
adapterType = method.getGenericReturnType();
}
// 从callAdapterFactories中获取到合适的CallAdapter,对Call进行转换
CallAdapter<ResponseT, ReturnT> callAdapter =
createCallAdapter(retrofit, method, adapterType, annotations);
Type responseType = callAdapter.responseType();
// 忽略部分检查错误的代码
// 从converterFactories中获取到合适的responseConverter
Converter<ResponseBody, ResponseT> responseConverter =
createResponseConverter(retrofit, method, responseType);
okhttp3.Call.Factory callFactory = retrofit.callFactory;
if (!isKotlinSuspendFunction) {
return new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter);
} else {
// ...
// 暂时不分析对kotlin挂起函数的支持
}
}
暂时不分析kotlin挂起函数,先看普通函数的处理。拿到requestFactory、合适的callAdapter、合适的responseConverter,组成了新的CallAdapted,CallAdapted是HttpServiceMethod的一个子类。
scala
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) {
return callAdapter.adapt(call);
}
}
主厨CallAdapted上场了。
loadServiceMethod方法,最终得到的就是这个CallAdapted,它也有着自己的四个厨娘的调用权:requestFactory(功能:对请求的解析和创建)、callFactory(默认就是OkhttpClient)、responseConverter和callAdapter。
4.工作部署:invoke
HttpServiceMethod.invoke一调用,主厨开始进行最后的部署工作,并分配了一个部署指挥官。主厨将三个帮手的指挥权传递给部署指挥官,交由他完成下一步工作。
less
@Override
final @Nullable ReturnT invoke(Object[] args) {
Call<ResponseT> call = new OkHttpCall<>(requestFactory, args, callFactory, responseConverter);
return adapt(call, args);
}
invoke方法只有两行,创建一个OkHttpCall对象,执行adapt(call, args)。
先要说明一点,这里的OkHttpCall是Retrofit包中的一个类,并不是OkHttp包中的,但这个类封装了对OKHttp中Call请求的创建和处理。
看看OkHttpCall的构造函数和它的成员变量,有requestFactory、callFactory,、responseConverter,通过这几个,它的能力便可以想象得到。
再回到adapter方法的分析,loadServiceMethod返回的CallAdapted对adapt进行了重写,返回了callAdapter.adapt(call)。
来看看默认的CallAdapterFactory和其提供的Adapter:
kotlin
final class DefaultCallAdapterFactory extends CallAdapter.Factory {
@Nullable
private final Executor callbackExecutor;
DefaultCallAdapterFactory(@Nullable Executor callbackExecutor) {
this.callbackExecutor = callbackExecutor;
}
@Nullable
public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
if (getRawType(returnType) != Call.class) {
return null;
} else if (!(returnType instanceof ParameterizedType)) {
throw new IllegalArgumentException("Call return type must be parameterized as Call<Foo> or Call<? extends Foo>");
} else {
// 如果没有使用SkipCallbackExecutor注解,那就返回ExecutorCallbackCall
final Type responseType = Utils.getParameterUpperBound(0, (ParameterizedType)returnType);
final Executor executor = Utils.isAnnotationPresent(annotations, SkipCallbackExecutor.class) ? null : this.callbackExecutor;
return new CallAdapter<Object, Call<?>>() {
public Type responseType() {
return responseType;
}
public Call<Object> adapt(Call<Object> call) {
return (Call)(executor == null ? call : new ExecutorCallbackCall(executor, call));
}
};
}
}
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;
}
public void enqueue(final Callback<T> callback) {
Objects.requireNonNull(callback, "callback == null");
this.delegate.enqueue(new Callback<T>() {
public void onResponse(Call<T> call, Response<T> response) {
ExecutorCallbackCall.this.callbackExecutor.execute(() -> {
if (ExecutorCallbackCall.this.delegate.isCanceled()) {
callback.onFailure(ExecutorCallbackCall.this, new IOException("Canceled"));
} else {
callback.onResponse(ExecutorCallbackCall.this, response);
}
});
}
public void onFailure(Call<T> call, Throwable t) {
ExecutorCallbackCall.this.callbackExecutor.execute(() -> {
callback.onFailure(ExecutorCallbackCall.this, t);
});
}
});
}
public boolean isExecuted() {
return this.delegate.isExecuted();
}
public Response<T> execute() throws IOException {
return this.delegate.execute();
}
public void cancel() {
this.delegate.cancel();
}
public boolean isCanceled() {
return this.delegate.isCanceled();
}
public Call<T> clone() {
return new ExecutorCallbackCall(this.callbackExecutor, this.delegate.clone());
}
public Request request() {
return this.delegate.request();
}
public Timeout timeout() {
return this.delegate.timeout();
}
}
}
这里返回了ExecutorCallbackCall,对传入的OkHttpCall对象做了一层简单的封装,enqueue方法将回调函数运行在主线程中。可以认为这里使用了代理模式。
这里简单理解为部署完成,最后部署指挥官便是ExecutorCallbackCall。
5.做菜了:enqueue
当用户要菜时(发起请求时),部署指挥官开始指挥工作,稍后便将美食制作完成:
kotlin
service.paperList(0)
.enqueue(object : Callback<MainPaperList> {
override fun onResponse(
call: Call<MainPaperList>,
response: Response<MainPaperList>
) {
// 请求成功
}
override fun onFailure(call: Call<MainPaperList>, t: Throwable) {
// 请求异常
}
})
部署指挥官的工作就是指挥,底层工作仍是别人执行:
分析便止于此。
我想以容易理解的方式进行源码解读,但是我给出的一个餐厅模型对于源码中部分逻辑仍然难以适配,因此只做入门理解使用。
因为能力有限,以上分析会有部分理解错误之处,希望各位提出。
五.总结
Retrofit作为一个轻量的网络请求封装库,却有着丰富和优雅的设计。这是非常值得大家分析学习的。
在分析源码的过程中,下面几点会更好地帮助到你:
1.理解类名
优秀的框架通过类名便可以看出这个类功能的一二。
比如XXFactory,一般都是工厂模式,对应会有一个create方法区创建一个XX。
XXAdapter和XXConvert,名字更是直接表明是一个适配器或者转换类。
2.看看类的成员变量,判断类的能力
面向对象的一大特征便是封装。类的成员变量,便是类所封装和承载的信息。对于不熟悉的类,不妨先看看他的成员变量有哪些,看看他有什么能力。
3.阅读注释
有时候看注释也会不理解,但不妨碍注释给我的启示作用。
推荐一个免费的IDEA插件Translation,助你轻松应对英文注释。