- App应用程序通过Retrofit 请求网络,实际上是使用Retrofit接口层封装请求参数,之后由OkHttp完成后续的请求操作。
- 在服务器返回数据之后,OkHttp将原始的结果交给Retrofit,Retrofit根据用户的需求对结果进行解析。
一、retrofit框架网络请求过程7个步骤:
-
- 添加Retrofit库的依赖,添加网络权限
-
- 创建接收服务器返回数据的类
-
- 创建用于描述网络请求的接口
-
- 创建Retrofit实例
-
- 创建网络请求接口实例
-
- 发送网络请求(同步/异步)
-
- 处理服务器返回的数据
或者也可以将网络通信归纳成如下八步:
- 创建retrofit实例
- 定义一个网络请求接口并为接口中的方法添加注解
- 通过动态代理生产网络请求对象
- 通过网络请求适配器将网络请求对象进行平台适配
- 通过网络请求适配器发送网络请求
- 通过数据转换器解析数据
- 通过回调执行器切换线程
- 用户在主线程处理返回结果
二、代理
-
静态代理模式:为其他对象提供一种代理,用以控制对这个对象的访问
-
动态代理模式:代理类在程序运行时创建的代理方式
相比静态代理,动态代理的优势它能很方便的对我们代理类的函数进行统一的处理,不用频繁的修改每一个代理类函数
(1)jdk动态代理–需要客户端辅助写些接口来操作
(2)CGLIB–可以直接修改字节码 -
每个代理类的对象都会关联一个表示内部处理逻辑的InvocationHandler接口的实现
-
invoke方法的参数中可以获取参数
-
invoke方法的返回值被返回给使用者
三、Retrofit源码解析
Retrofit中成员变量:
-
private final Map<Method, ServiceMethod<?>> serviceMethodCache = new ConcurrentHashMap<>(); //key是Method为http请求的方法,value是ServiceMethod代表网络请求接口中对方法进行注解之后,通过进行解析之后的对象,跟注解中get、put等是成对出现、一一对应的。serviceMethodCache主要用于缓存,存储一些网络请求的相关配置和网络请求的方法、数据转换器、网络请求适配器等等。
-
final okhttp3.Call.Factory callFactory; //请求网络的OkHttp的工厂,默认为OkHttpClient,该工厂的作用就是生产OkHttpClient
-
final HttpUrl baseUrl; //网络请求的基地址,跟接口注解中的相对地址可以拼接成一个完整的请求地址
-
final List<Converter.Factory> converterFactories; //数据转换器工厂的集合,数据转换器就是对请求网络之后得到的Response所进行的转换,转换成应用java对象,默认情况下使用的是GsonCoverterFactory。该集合就是用于放置数据转换器的工厂,同时这个工厂的作用也是用于生产所需要的数据转换器
-
final List<CallAdapter.Factory> callAdapterFactories; //网络请求适配器的工厂集合,适配器就是把call对象转换成其他类型,比如Rxjava平台的call。该集合就是用于放置网络适配器工厂,同时这个工厂的作用也是用于生产CallAdapter
-
final @Nullable Executor callbackExecutor; //用于执行回调,在Android平台中,默认使用的是MainThreadExecutor,即主线程中的executor
-
final boolean validateEagerly; // 表示的是一个标志位,是否需要立即解析接口中的方法,该标志位是用于动态代理中解析定义好接口中的方法和注解当中
Retrofit内部类Builder的成员变量:
-
private final Platform platform; //Retrofit适配的平台,包括android、ios、java8,默认情况下使用的是android平台
-
private @Nullable okhttp3.Call.Factory callFactory; //表示请求网络的okhttp工厂,默认情况下使用的是okhttp来进行网络请求的,默认值为OkHttpClient
-
private @Nullable HttpUrl baseUrl; //网络请求的Url基地址
-
private final List<Converter.Factory> converterFactories = new ArrayList<>(); //数据转换器工厂的集合,数据转换器就是对请求网络之后得到的Response所进行的转换,转换成应用java对象,默认情况下使用的是GsonCoverterFactory。该集合就是用于放置数据转换器的工厂,同时这个工厂的作用也是用于生产所需要的数据转换器
-
private final List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(); //网络请求适配器的工厂集合,适配器就是把call对象转换成其他类型,比如Rxjava平台的call。该集合就是用于放置网络适配器工厂,同时这个工厂的作用也是用于生产CallAdapter
-
private @Nullable Executor callbackExecutor; //用于执行回调,在Android平台中,默认使用的是MainThreadExecutor,即主线程中的executor
-
private boolean validateEagerly; /// 表示的是一个标志位,是否需要立即解析接口中的方法,该标志位是用于动态代理中解析定义好接口中的方法和注解当中
Builder类中的2~7成员变量跟Retrofit类中的2-7成员变量是一样的
Retrofit的build()
作用:build()方法就是将Retrofit类中所有成员变量配置完毕。
public Retrofit build() {
if (baseUrl == null) {
throw new IllegalStateException("Base URL required.");
}
okhttp3.Call.Factory callFactory = this.callFactory;
if (callFactory == null) {
callFactory = new OkHttpClient(); //默认使用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);
}
CallAdapter
RxJavaCallAdapterFactory
retrofit请求
-
同步:OkHttpCall.execute()
-
异步:OkHttpCall.enqueue()
Retrofit采用的设计模式:
-
- 构建者模式
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://***.***.com/") //设置网络请求的url地址,这个是基地址
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.addConverterFactory(AppGsonConverterFactory.create())
.build();
-
- 工厂模式
CallAdapter.Factory
/**
* Creates {@link CallAdapter} instances based on the return type of {@linkplain
* Retrofit#create(Class) the service interface} methods.
*/
abstract class Factory {
/**
* Returns a call adapter for interface methods that return {@code returnType}, or null if it
* cannot be handled by this factory.
*/
public abstract @Nullable CallAdapter<?, ?> get(
Type returnType, Annotation[] annotations, Retrofit retrofit);
/**
* Extract the upper bound of the generic parameter at {@code index} from {@code type}. For
* example, index 1 of {@code Map<String, ? extends Runnable>} returns {@code Runnable}.
*/
protected static Type getParameterUpperBound(int index, ParameterizedType type) {
return Utils.getParameterUpperBound(index, type);
}
/**
* Extract the raw class type from {@code type}. For example, the type representing {@code
* List<? extends Runnable>} returns {@code List.class}.
*/
protected static Class<?> getRawType(Type type) {
return Utils.getRawType(type);
}
}
RxJava2CallAdapterFactory和DefaultCallAdapterFactory 继承于CallAdapter.Factory类,并复写get()方法来返回不同的CallAdapter类型
-
- 静态工厂模式
public class Platform {
private static final Platform PLATFORM = findPlatform();
... ...
public static Platform get() {
return PLATFORM;
}
... ...
/** Attempt to match the host runtime to a capable Platform implementation. */
private static Platform findPlatform() {
if (isAndroid()) {
return findAndroidPlatform();
} else {
return findJvmPlatform();
}
}
... ...
-
- 外观/门面设计模式
定义:外部与一个子系统进行通信,必须通过一个统一外观的对象(也就是门面)来进行。为这个子系统的一组接口提供一个一致的界面。对外提供统一的接口,方便与外部之间的通信
- 外观/门面设计模式
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://***.***.com/") //设置网络请求的url地址,这个是基地址
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.addConverterFactory(AppGsonConverterFactory.create())
.build();
Retrofit类的设计就是一个外观模式
-
- 策略模式
Retrofit中的CallAdapter采用了策略模式
策略模式和工厂模式的区别:策略模式强调的是不同对象的策略方法的具体实现,侧重于方法的实现;工厂模式强调的是生产对象
- 策略模式
-
- 适配器模式
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://***.***.com/") //设置网络请求的url地址,这个是基地址
.addCallAdapterFactory(RxJava2CallAdapterFactory.create()) //这个地方采用适配器模式
.addConverterFactory(AppGsonConverterFactory.create())
.build();
CallAdapter类中adapter()方法
T adapt(Call<R> call);
-
- 动态代理模式
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);
}
args = args != null ? args : emptyArgs;
return platform.isDefaultMethod(method)
? platform.invokeDefaultMethod(method, service, proxy, args)
: loadServiceMethod(method).invoke(args);
}
});
}
-
- 观察者设计模式
Call/OkHttpCall --> 被观察者
异步请求的Callback -->观察者
- 观察者设计模式