一.Retrofit实例的创建
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com")
.build();
设计模式:
1.建造者模式:
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。通俗的说就是:建造者模式就是如何一步步构建一个包含多个组成部件的对象,相同的构建过程可以创建不同的产品
优点:
在建造者模式中, 客户端不必知道产品内部组成的细节,将产品本身与产品的创建过程解耦,使得相同的创建过程可以创建不同的产品对象。
缺点:
如果产品的内部变化复杂,可能会导致需要定义很多具体建造者类来实现这种变化,导致系统变得很庞大
2.门面模式
门面模式(Facade Pattern):外部与一个子系统的通信必须通过一个统一的外观对象进行,为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
优点:
-对客户屏蔽子系统组件,减少了客户处理的对象数目并使得子系统使用起来更加容易。通过引入门面模式,客户代码将变得很简单,与之关联的对象也很少。
-实现了子系统与客户之间的松耦合关系,这使得子系统的组件变化不会影响到调用它的客户类,只需要调整外观类即可。
缺点:
-不能很好地限制客户使用子系统类。
-在不引入抽象外观类的情况下,增加新的子系统可能需要修改外观类或客户端的源代码,违背了“开闭原则”。
二.Retrofit的使用
public interface GitHubService {
@GET("users/{user}/repos")
Call<List<Repo>> listRepos(@Path("user") String user);
}
GitHubService service = retrofit.create(GitHubService.class);
Call<List<Repo>> repos = service.listRepos("octocat");
retrofit.create(GitHubService.class) 先看下 如何创建 Api 实例:
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<Object, Object> serviceMethod =
(ServiceMethod<Object, Object>) loadServiceMethod(method);
OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
return serviceMethod.adapt(okHttpCall);
}
});
使用了动态代理,对方法调用的真正执行逻辑在 InvocationHandler.
三.接口如何转为真正的请求
上面我们知道真正的请求是通过InvocationHandler 里面,来执行真正的逻辑
ServiceMethod<Object, Object> serviceMethod =
(ServiceMethod<Object, Object>) loadServiceMethod(method);
OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
return serviceMethod.adapt(okHttpCall);
ServiceMethod 负责把接口方法注解转换为http表示
OkhttpCall 负责将serviceMethod转换为Okhttp3.Call
1.ServiceMethod
/** Adapts an invocation of an interface method into an HTTP call. */
将一个接口调用转化为 HTTP 请求
ServiceMethod 的作用是将我们对 Api Service 对接口的调用转化为HTTP call
ServiceMethod<Object, Object> serviceMethod = (ServiceMethod<Object, Object>) `loadServiceMethod(method)`;
ServiceMethod<?, ?> `loadServiceMethod(Method method)` {
ServiceMethod<?, ?> result = serviceMethodCache.get(method);
if (result != null) return result;
//省略
return result;
}
ServiceMethod 会对每个方法,做缓存处理,ServiceCache 内存在的直接返回结果
ServiceMethod 的构造函数:
ServiceMethod(Builder<R, T> builder) {
//网络请求工厂 默认值为 okhttp3.OkHttpClient
this.callFactory = builder.retrofit.callFactory();
//网络请求适配器 把Call 请求适配各个平台
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;
}
1.1callAdapter
/**
* Adapts a {@link Call} with response type {@code R} into the type of {@code T}. Instances are
* created by {@linkplain Factory a factory} which is
* {@linkplain Retrofit.Builder#addCallAdapterFactory(Factory) installed} into the {@link Retrofit}
* instance.
*/
public interface CallAdapter<R, T> {
T adapt(Call<R> call);
}
CallAdapter 主要就是将 R 转为 T,
我们看下Retrofit 默认的 CallAdapter
// Make a defensive copy of the adapters and add the default Call adapter.
List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
callAdapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));
CallAdapter.Factory defaultCallAdapterFactory(@Nullable Executor callbackExecutor) {
if (callbackExecutor != null) {
return new ExecutorCallAdapterFactory(callbackExecutor);
}
return DefaultCallAdapterFactory.INSTANCE;
}
默认的 ExecutorCallAdapterFactory 主要做的事 就是将 调用 enqueue 时,将结果回调至 传入的 callbackExecutor (默认值 为 MainThreadExecutor),
所以我们在调用 enqueue 时返回的 callback 内的数据 是在 主线程,就是在这里处理的
有一个疑问是,我们传入了多个 CallAdapter Retrofit 是如何处理 ?
Retrofit 会遍历CallAdapters 根据 returnType 来自动选择合适的 CallAdapter
public CallAdapter<?, ?> callAdapter(Type returnType, Annotation[] annotations) {
return nextCallAdapter(null, returnType, annotations);
}
public CallAdapter<?, ?> nextCallAdapter(@Nullable CallAdapter.Factory skipPast, Type returnType,
Annotation[] annotations) {
// 省略
int start = callAdapterFactories.indexOf(skipPast) + 1;
for (int i = start, count = callAdapterFactories.size(); i < count; i++) {
//调用 callAdapter 的 get 直至 不为 null
CallAdapter<?, ?> adapter = callAdapterFactories.get(i).get(returnType, annotations, this);
if (adapter != null) {
return adapter;
}
}
// 省略
}
//DefaultCallAdapterFactory 内的实现
@Override
public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
// 如果返回值类型 不是 Call.class 直接返回 null, 寻找下一个
if (getRawType(returnType) != Call.class) {
return null;
}
}
1.2responseConverter
public interface Converter<F, T> {
T convert(F value) throws IOException;
}
Converter 主要作用是将 F 转 为 T
我们看下convert 函数被调用的地方
ServiceMethoid类内的
/** Builds a method return value from an HTTP response body. */
R toResponse(ResponseBody body) throws IOException {
return responseConverter.convert(body);
}
F 就是 服务器返回的 body , T是什么呢, 通过 CallAdapter的获取, 初步判断与 return type 有关
Retrofit类内
public <T> Converter<ResponseBody, T> responseBodyConverter(Type type, Annotation[] annotations) {
获取 ResponseBodyConverter 对象
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) {
//noinspection unchecked
return (Converter<ResponseBody, T>) converter;
}
}
//省略
}
在 Retrofit build方法内
会先添加一个 converter BuiltInConverters
final class BuiltInConverters extends Converter.Factory {
@Override
public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations,
Retrofit retrofit) {
if (type == ResponseBody.class) {
// 判断注解内 是否有 Streaming.class , 有返回 StreamingResponseBodyConverter, 其他返回 BufferingResponseBodyConverter
return Utils.isAnnotationPresent(annotations, Streaming.class)
? StreamingResponseBodyConverter.INSTANCE
: BufferingResponseBodyConverter.INSTANCE;
}
if (type == Void.class) {
return VoidResponseBodyConverter.INSTANCE;
}
return null;
}
}
2.OkhttpCall
OkhttpCall implements 了 retrofit2.Call
平时我们调用
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com")
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.build();
Api service = retrofit.create(Api.class);
// enqueue 的真正执行逻辑就是 在 OkhttpCall 里面实现的
service.getUser().enqueue(); //异步
service.getUser().execute() // 同步
@Override public Response<T> execute() throws IOException {
okhttp3.Call call;
call = rawCall;
if (call == null) {
try {
//1.创建 call 对象
call = rawCall = createRawCall();
} catch (IOException | RuntimeException | Error e) {
throwIfFatal(e); // Do not assign a fatal error to creationFailure.
creationFailure = e;
throw e;
}
}
}
// 2.执行请求 3. 解析response
return parseResponse(call.execute());
}
OkhttpCall excute() 主要做了三件事
- 创建 okhttp3.Call 对象
- 执行请求
- 解析response
我们看下 okhttp3.Call对象的创建, 调用 ServiceMethod 的 toCall 创建, 这时候 Retrofit 去解析我们写在 接口上的各种注解,
解析成功 我们平时 Request 对象的各种参数
private okhttp3.Call createRawCall() throws IOException {
okhttp3.Call call = serviceMethod.toCall(args);
if (call == null) {
throw new NullPointerException("Call.Factory returned null.");
}
return call;
}
//创建 HTTP 请求 通过方法参数
/** Builds an HTTP request from method arguments. */
okhttp3.Call toCall(@Nullable Object... args) throws IOException {
RequestBuilder requestBuilder = new RequestBuilder(httpMethod, baseUrl, relativeUrl, headers,
contentType, hasBody, isFormEncoded, isMultipart);
//通过 ParameterHandler 解析注解
@SuppressWarnings("unchecked") // It is an error to invoke a method with the wrong arg types.
ParameterHandler<Object>[] handlers = (ParameterHandler<Object>[]) parameterHandlers;
// callFactory 默认值为 new OkHttpClient()
return callFactory.newCall(requestBuilder.build());
}
解析Response
Response<T> parseResponse(okhttp3.Response rawResponse) throws IOException {
ResponseBody rawBody = rawResponse.body();
// Remove the body's source (the only stateful object) so we can pass the response along.
rawResponse = rawResponse.newBuilder()
.body(new NoContentResponseBody(rawBody.contentType(), rawBody.contentLength()))
.build();
int code = rawResponse.code();
if (code < 200 || code >= 300) {
try {
// Buffer the entire body to avoid future I/O.
ResponseBody bufferedBody = Utils.buffer(rawBody);
return Response.error(bufferedBody, rawResponse);
} finally {
rawBody.close();
}
}
if (code == 204 || code == 205) {
rawBody.close();
return Response.success(null, rawResponse);
}
ExceptionCatchingRequestBody catchingBody = new ExceptionCatchingRequestBody(rawBody);
try {
// 将 Response 转化为 T
T body = serviceMethod.toResponse(catchingBody);
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;
}
}
调用 ServiceMethod 将 response 转为 T, 根据 我们Api 接口的 Return Type 决定 responseConverter 对象
/** Builds a method return value from an HTTP response body. */
R toResponse(ResponseBody body) throws IOException {
return responseConverter.convert(body);
}
异步 enqueue(Callback<T> callback)
调用 okhttp3.Call#enqueue(Callback responseCallback) 来实现, 将返回的数据callback ,其他步骤与 excute 一样
- callAdapter.adapt(call)
T adapt(Call<R> call) {
return callAdapter.adapt(call);
}
final class DefaultCallAdapterFactory extends CallAdapter.Factory {
static final CallAdapter.Factory INSTANCE = new DefaultCallAdapterFactory();
@Override
public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
// 默认的 CallAdapter , T adapt(Call<R> call) , T 就是 Call<Object>, R就是 Object
return new CallAdapter<Object, Call<?>>() {
@Override public Type responseType() {
return responseType;
}
@Override public Call<Object> adapt(Call<Object> call) {
return call;
}
};
}
}
至此 整个 网络请求结束 :
1.通过 ServiceMethod 的 ParameterHandler 解析参数 ,通过 ApiService 的 方法 return type 选择合适的 callAdapter 和 converter
ServiceMethod<Object, Object> serviceMethod = (ServiceMethod<Object, Object>) loadServiceMethod(method);
2. 包装 Okhttp#call ,执行网络请求, 解析 response
OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
3. 将reponse 通过 convert 转为 method return type
serviceMethod.adapt(okHttpCall);
参考文章链接 :
https://www.jianshu.com/p/45cb536be2f4
https://juejin.im/post/5a7ff9b3f265da4e9a49567a
https://blog.piasy.com/2016/06/25/Understand-Retrofit/