深入浅出retrofit

简介

Retrofit 是一个 RESTful 的 HTTP 网络请求框架的封装。网络请求的工作本质上是 OkHttp 完成,而 Retrofit 仅负责 网络请求接口层的封装(请求参数、Header、Url 等信息)。

流程

源码分析

  1. 创建Retrofit实例
  2. 创建 网络请求接口实例 并 配置网络请求参数
  3. 发送网络请求(封装了 数据转换、线程切换的操作)
  4. 处理服务器返回的数据

创建Retrofit实例

1
2
3
4
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://fanyi.youdao.com/")
.addConverterFactory(GsonConverterFactory.create())
.build();

成功建立一个Retrofit对象的标准:配置好Retrofit类里的成员变量,即配置好:

  1. serviceMethod:包含所有网络请求信息的对象
  2. baseUrl:网络请求的url地址
  3. callFactory:网络请求工厂
  4. adapterFactories:网络请求适配器工厂的集合
  5. converterFactories:数据转换器工厂的集合
  6. callbackExecutor:回调方法执行器
serviceMethod

将请求的注解信息封装成serviceMethod对象

baseUrl
1
2
3
4
5
6
7
8
9
10
11
12
13
public Builder baseUrl(String baseUrl) {
HttpUrl httpUrl = HttpUrl.parse(baseUrl);
return baseUrl(httpUrl);
}

public Builder baseUrl(HttpUrl baseUrl) {
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;
}

把String类型的url参数转化为适合OKhttp的HttpUrl类型,检测最后一个碎片来检查URL参数是不是以”/“结尾,不是就抛出异常。

callFactory

网络请求工厂,默认为OkHttpClient。

adapterFactories

CallAdapterFactory:该Factory生产的是CallAdapter,那么CallAdapter又是什么呢?将默认的网络请求执行器(OkHttpCall)转换成适合被不同平台来调用的网络请求执行器形式。

  1. Call在Retrofit里默认是OkHttpCall
  2. 在Retrofit中提供了四种CallAdapterFactory: ExecutorCallAdapterFactory(默认)、GuavaCallAdapterFactory、Java8CallAdapterFactory、RxJavaCallAdapterFactory
converterFactories
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public final class GsonConverterFactory extends Converter.Factory {
public static GsonConverterFactory create() {
return create(new 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) {
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) {
TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
return new GsonRequestBodyConverter<>(gson, adapter);
}
}

创建一个含有Gson对象实例的GsonConverterFactory并放入到数据转换器工厂converterFactories里

  1. 即Retrofit默认使用Gson进行解析
  2. 若使用其他解析方式(如Json、XML或Protocobuf),也可通过自定义数据解析器来实现(必须继承 Converter.Factory)
callbackExecutor
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
static class Android extends Platform {
@Override public Executor defaultCallbackExecutor() {
return new MainThreadExecutor();
}

@Override CallAdapter.Factory defaultCallAdapterFactory(@Nullable Executor callbackExecutor) {
if (callbackExecutor == null) throw new AssertionError();
return new ExecutorCallAdapterFactory(callbackExecutor);
}

static class MainThreadExecutor implements Executor {
private final Handler handler = new Handler(Looper.getMainLooper());

@Override public void execute(Runnable r) {
handler.post(r);
}
}
}

默认回调方法执行器作用是:切换线程(子线程 - 主线程)

调用retrofit的create方法

使用动态代理根据接口创建实例对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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 {
// 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<Object, Object> serviceMethod =
(ServiceMethod<Object, Object>) loadServiceMethod(method);
OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
return serviceMethod.callAdapter.adapt(okHttpCall);
}
});

根据第一步配置好的ServiceMethod对象和输入的请求参数创建okHttpCall对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<--OkHttpCall类 -->
public class OkHttpCall {
private final ServiceMethod<T> serviceMethod; // 含有所有网络请求参数信息的对象
private final Object[] args; // 网络请求接口的参数
private okhttp3.Call rawCall; //实际进行网络访问的类
private Throwable creationFailure; //几个状态标志位
private boolean executed;
private volatile boolean canceled;

<--OkHttpCall构造函数 -->
public OkHttpCall(ServiceMethod<T> serviceMethod, Object[] args) {
// 传入了配置好的ServiceMethod对象和输入的请求参数
this.serviceMethod = serviceMethod;
this.args = args;
}

将第二步创建的OkHttpCall对象传给第一步创建的serviceMethod对象中对应的网络请求适配器工厂的adapt()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<--  adapt()详解-->
public <R> Call<R> adapt(Call<R> call) {
return new ExecutorCallbackCall<>(callbackExecutor, call);
}

ExecutorCallbackCall(Executor callbackExecutor, Call<T> delegate) {
this.delegate = delegate;
// 把上面创建并配置好参数的OkhttpCall对象交给静态代理delegate
// 静态代理和动态代理都属于代理模式
// 静态代理作用:代理执行被代理者的方法,且可在要执行的方法前后加入自己的动作,进行对系统功能的拓展

this.callbackExecutor = callbackExecutor;
// 传入上面定义的回调方法执行器
// 用于进行线程切换
}

返回对象类型:Android默认的是Call<>;若设置了RxJavaCallAdapterFactory,返回的则是Observable<>

请求

  1. 同步请求 execute
  2. 异步请求 enqueue

总结

Retrofit 本质上是一个 RESTful 的HTTP 网络请求框架的封装,即通过 大量的设计模式 封装了 OkHttp ,使得简洁易用。具体过程如下:

  1. Retrofit 将 Http请求 抽象 成 Java接口
  2. 在接口里用 注解 描述和配置 网络请求参数
  3. 用动态代理 的方式,动态将网络请求接口的注解 解析 成HTTP请求
  4. 最后执行HTTP请求
您的支持是我原创的动力