设计模式:建造者模式、工厂方法模式、外观模式、代理模式、单例模式、策略模式、装饰模式、适配器模式、代理模式
一、Retrofit网络请求步骤
- 通过解析网络请求接口的注解 配置 网络请求参数
- 通过动态代理 生成 网络请求对象
- 通过网络请求适配器 将 网络请求对象 进行平台适配
- 通过网络请求执行器 发送网络请求
- 通过数据转换器 解析服务器返回的数据
- 通过回调执行器 切换线程
- 用户在主线程处理返回结果
- Call网络请求执行器
作用:创建HTTP网络请求 - CallAdpater网络请求适配器
作用:网络请求执行器的适配器,将默认的网络请求执行器转换成适合被不同平台调用的网络请求执行器 - Converter数据转换器
作用:将返回数据解析成我们需要的数据类型 - CallBackExecutor回调执行器
作用:线程切换(子线程 -->主线程)
二、源码解析
(1)创建Retrofit实例
private static Retrofit provideRetrofit() {
File cacheFile = new File(CPApplication.getContext().getCacheDir(), "cache");
Cache cache = new Cache(cacheFile, 1024 * 1024 * 100); //100Mb
OkHttpClient client = new OkHttpClient.Builder()
.cache(cache) //设置缓存
.connectTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)
.writeTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)
.readTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)
.addNetworkInterceptor(getRequestHeader())
.addInterceptor(getHttpLoggingInterceptor())
.addInterceptor(getResponseHeader())
.addInterceptor(getCacheInterceptor())
.build();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(NetworkInterface.HOST)//设置网络请求的Url地址
.addConverterFactory(GsonConverterFactory.create())//设置数据解析器
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())//支持RxJava平台
.client(client)
.build();
return retrofit;
}
(2)Retrofit类源码
public final class Retrofit {
//网络请求配置对象
private final Map<Method, ServiceMethod<?, ?>> serviceMethodCache = new ConcurrentHashMap<>();
//网络请求工厂:生产网络请求器
final okhttp3.Call.Factory callFactory;
//网络请求的url地址
final HttpUrl baseUrl;
//网络请求适配器工厂的集合:放置网络请求适配器工厂
final List<Converter.Factory> converterFactories;
//数据转换器工厂的集合:放置数据转换器工厂
final List<CallAdapter.Factory> callAdapterFactories;
//回调方法执行器
final @Nullable Executor callbackExecutor;
//是否提前对业务接口中的注解进行验证转换的标志位
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;
}
//code...
}
成功建立一个Retrofit对象的标准:配置好Retrofit类里的成员变量
- serviceMethod:包含所有网络请求信息的对象
- baseUrl:网络请求的url地址
- callFactory:网络请求工厂
- adapterFactories:网络请求适配器工厂的集合
- converterFactories:数据转换器工厂的集合
- callbackExecutor:回调方法执行器
(3)Builder类源码
public static final class Builder {
//Builder类的成员变量与Retrofit类的成员变量是对应的。所以Retrofit类的成员变量基本上是通过Builder类进行配置
private final Platform platform;
private @Nullable okhttp3.Call.Factory callFactory;
private @Nullable HttpUrl baseUrl;
private final List<Converter.Factory> converterFactories = new ArrayList<>();
private final List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>();
private @Nullable Executor callbackExecutor;
private boolean validateEagerly;
Builder(Platform platform) {
this.platform = platform;
}
//Builder的构造方法
public Builder() {
//用this调用自己的有参构造方法Builder(Platform platform)
this(Platform.get());
}
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;
}
//设置网络请求执行器
public Builder client(OkHttpClient client) {
return callFactory(Objects.requireNonNull(client, "client == null"));
}
//使用okhttp进行网络请求
public Builder callFactory(okhttp3.Call.Factory factory) {
this.callFactory = Objects.requireNonNull(factory, "factory == null");
return this;
}
//用于配置Retrofit类的网络请求url地址
public Builder baseUrl(String baseUrl) {
//把String类型的url参数转化为适合OKhttp的HttpUrl类型
Objects.requireNonNull(baseUrl, "baseUrl == null");
//最终返回带httpUrl类型参数的baseUrl()
return baseUrl(HttpUrl.get(baseUrl));
}
public Builder baseUrl(HttpUrl baseUrl) {
Objects.requireNonNull(baseUrl, "baseUrl == null");
//把URL参数分割成几个路径碎片
List<String> pathSegments = baseUrl.pathSegments();
//检测最后一个碎片来检查URL参数是不是以"/"结尾
if (!"".equals(pathSegments.get(pathSegments.size() - 1))) {
throw new IllegalArgumentException("baseUrl must end in /: " + baseUrl);
}
this.baseUrl = baseUrl;
return this;
}
//创建GsonConverterFactory放入到 converterFactories数组设置数据解析器
public Builder addConverterFactory(Converter.Factory factory) {
converterFactories.add(Objects.requireNonNull(factory, "factory == null"));
return this;
}
//创建RxJava2CallAdapterFactory放入到 callAdapterFactories数组支持RxJava平台
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;
}
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);
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());
//最终返回一个Retrofit的对象,并传入上述已经配置好的成员变量
return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories),
unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);
}
}
Platform源码
class Platform {
//将findPlatform()赋给静态变量
private static final Platform PLATFORM = findPlatform();
static Platform get() {
return PLATFORM;
}
private static Platform findPlatform() {
try {
//要求JVM查找并加载指定的类
Class.forName("android.os.Build");
//如果是Android平台,就创建并返回一个Android对象并返回
if (Build.VERSION.SDK_INT != 0) {
return new Android();
}
} catch (ClassNotFoundException ignored) {
}
return new Platform(true);
}
//code...
}
Android源码
//用于接收服务器返回数据后进行线程切换在主线程显示结果
static final class Android extends Platform {
Android() {
super(Build.VERSION.SDK_INT >= 24);
}
@Override
public Executor defaultCallbackExecutor() {
//返回一个默认的回调方法执行器
return new MainThreadExecutor();
}
static class MainThreadExecutor implements Executor {
//获取与Android主线程绑定的Handler
private final Handler handler = new Handler(Looper.getMainLooper());
@Override
public void execute(Runnable r) {
//在UI线程进行对网络请求返回数据处理等操作
handler.post(r);
}
}
}
GsonConverterFactory.creat()源码
public final class GsonConverterFactory extends Converter.Factory {
public static GsonConverterFactory create() {
//创建一个Gson对象
return create(new Gson());
}
@SuppressWarnings("ConstantConditions") // Guarding public API nullability.
public static GsonConverterFactory create(Gson gson) {
if (gson == null) throw new NullPointerException("gson == null");
//创建了一个含有Gson对象实例的GsonConverterFactory
return new GsonConverterFactory(gson);
}
private final Gson gson;
private GsonConverterFactory(Gson gson) {
this.gson = gson;
}
//code...
}
通过查看源码GsonConverterFactory.creat()是创建了一个含有Gson对象实例的GsonConverterFactory,并返回给addConverterFactory()
通过addConverterFactory方法将上面创建的GsonConverterFactory放入到converterFactories数组
(4)创建网络请求接口
retrofit.create(NetworkInterface.class).registerLogin("");
create源码
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 {
// 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);
}
return loadServiceMethod(method).invoke(args != null ? args : emptyArgs);
}
});
}
//一个 ServiceMethod 对象对应于网络请求接口里的一个方法
ServiceMethod<?> loadServiceMethod(Method method) {
//首先会尝试根据方法从缓存中取出 ServiceMethod 实例
ServiceMethod<?> result = serviceMethodCache.get(method);
if (result != null) return result;
synchronized (serviceMethodCache) {
//如果没有,在锁保护之后还会再尝试一次
result = serviceMethodCache.get(method);
if (result == null) {
//还是没有的情况下,创建 ServiceMethod,最后放到 serviceMethodCache 缓存里
result = ServiceMethod.parseAnnotations(this, method);
serviceMethodCache.put(method, result);
}
}
return result;
}
ServiceMethod的创建过程
查看ServiceMethod.parseAnnotations方法源码
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);
}
查看RequestFactory.parseAnnotations & Builder源码
static RequestFactory parseAnnotations(Retrofit retrofit, Method method) {
return new Builder(retrofit, method).build();
}
//code..
//控制ServiceMethod对象的生成流程
static final class Builder {
//code..
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() {
//解析网络请求接口中方法的注解。主要是解析获取Http请求的方法
for (Annotation annotation : methodAnnotations) {
//处理主要是调用此方法
parseMethodAnnotation(annotation);
}
if (httpMethod == null) {
throw methodError(method, "HTTP method annotation is required (e.g., @GET, @POST, etc.).");
}
if (!hasBody) {
if (isMultipart) {
throw methodError(method,
"Multipart can only be specified on HTTP methods with request body (e.g., @POST).");
}
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];
//parameterAnnotationsArray为方法中的每个参数创建一个ParameterHandler<?>对象并解析每个参数使用的注解类型
for (int p = 0, lastParameter = parameterCount - 1; p < parameterCount; p++) {
//该对象的创建过程就是对方法参数中注解进行解析
parameterHandlers[p] =
parseParameter(p, parameterTypes[p], parameterAnnotationsArray[p], p == lastParameter);
}
if (relativeUrl == null && !gotUrl) {
throw methodError(method, "Missing either @%s URL or @Url parameter.", httpMethod);
}
if (!isFormEncoded && !isMultipart && !hasBody && gotBody) {
throw methodError(method, "Non-body HTTP method cannot contain @Body.");
}
if (isFormEncoded && !gotField) {
throw methodError(method, "Form-encoded method must contain at least one @Field.");
}
if (isMultipart && !gotPart) {
throw methodError(method, "Multipart method must contain at least one @Part.");
}
return new RequestFactory(this);
}
//code...
}