概述
retrofit是okhttp网络框架的封装。
- App应用程序通过Retrofit请求网络,实际上是使用Retrofit接口层封装请求参数,之后由okhttp完成后续的请求操作。
- 在服务端返回数据之后,okhttp将原始的结果交给retrofit,retrofit根据用户的需求对结果进行解析。
动态代理了解
https://www.jianshu.com/p/f4208b50f638
通信八步
- 创建retrofit 实例
- 定义一个网络请求接口,并为接口中的方法添加注解(get post等)
- 通过 动态代理生成网络 请求对象。 其实就是解析网络请求接口中的注解,解析完之后来配置我们的网络请求参数。最终通过动态代理拦截生成网络请求对象的。
- 通过 网络请求适配器,将网络请求对象进行平台适配。
- 通过 网络请求执行器call 发送网络请求
- 通过 数据转化器 解析数据
- 通过 回调执行器 切换线程
- 用户在主线程处理返回结果
实现
public static RetrofitService getRetrofit() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(Api.APP_DOMAIN)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
retrofitService = retrofit.create(RetrofitService.class);
return retrofitService;
}
Retrofit 源码---七个成员变量的解释
public final class Retrofit {
<-------七个成员变量的解释------>
//key值:Method: http请求的方法
//value值:ServiceMethod:注解(网络请求接口中方法的注解)解析之后的对象就是ServiceMethod
//serviceMethodCache:作用:存储网络请求相关的配置,如网络请求的方法、数据转换器、网络请求适配器、网络请求工厂、基地址等
private final Map<Method, ServiceMethod<?, ?>> serviceMethodCache = new ConcurrentHashMap<>();
// 网络请求器的工厂
// 作用:生产网络请求器OkHttpClient
// Retrofit是默认使用okhttp
final okhttp3.Call.Factory callFactory;
//网络请求url的基地址
final HttpUrl baseUrl;
//数据转化器工厂集合:放置数据转换器的工厂
//工厂的作用是生成我们//数据转化器(converter)
//数据转化器作用:他对我们请求网络回来的结果response进行转换,把它转换成我们能用的java对象
final List<Converter.Factory> converterFactories;
// 网络请求适配器工厂的集合, 作用:放置网络请求适配器工厂
// 网络请求适配器工厂作用:生产网络请求适配器(CallAdapter)
// CallAdapter适配器作用:把call对象转换成其他类型,比如如果平台想支持rxjava的话,这个时候,可以把call转化成rxjava的call
final List<CallAdapter.Factory> callAdapterFactories;
//工厂模式:将类实例化的操作与使用对象的操作分开,这样客户端在使用的时候,不需要知道具体的参数,直接通过Factory提供给我们的静态方法就可以创建想要的对象
//用于执行回调,安卓中默认主线程的MainThreadExecutor
final @Nullable Executor callbackExecutor;
// 标志位
// 作用:是否提前对业务接口中的注解进行验证转换的标志位
final boolean validateEagerly;
}
Retrofit 源码---Retrofit类中的Builder类
使用Builder的时候,对Retrofit初始化
public static final class Builder {
//适配平台:比如android、ios、java8等,默认是android
private final Platform platform;
//以下同Retrofit类里面的成员变量的含义
private @Nullable okhttp3.Call.Factory callFactory;
private 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.get()
public Builder() {
this(Platform.get());
}
}
...
看一下Platform这个类
class Platform {
private static final Platform PLATFORM = findPlatform();
<---------1. get()方法,返回的是findPlatform(),看一下findPlatform()------------->
static Platform get() {
return PLATFORM;
}
<---------2. 看一下findPlatform()------------->
private static Platform findPlatform() {
try {
//通过这个类确定是android平台,下面看一下Android();
Class.forName("android.os.Build");
if (Build.VERSION.SDK_INT != 0) {
return new Android();
}
} catch (ClassNotFoundException ignored) {
}
try {
//通过这个类确定是java8平台。
Class.forName("java.util.Optional");
return new Java8();
} catch (ClassNotFoundException ignored) {
}
return new Platform();
}
@Nullable Executor defaultCallbackExecutor() {
return null;
}
CallAdapter.Factory defaultCallAdapterFactory(@Nullable Executor callbackExecutor) {
if (callbackExecutor != null) {
return new ExecutorCallAdapterFactory(callbackExecutor);
}
return DefaultCallAdapterFactory.INSTANCE;
}
boolean isDefaultMethod(Method method) {
return false;
}
@Nullable Object invokeDefaultMethod(Method method, Class<?> declaringClass, Object object,
@Nullable Object... args) throws Throwable {
throw new UnsupportedOperationException();
}
@IgnoreJRERequirement // Only classloaded and used on Java 8.
static class Java8 extends Platform {
@Override boolean isDefaultMethod(Method method) {
return method.isDefault();
}
@Override Object invokeDefaultMethod(Method method, Class<?> declaringClass, Object object,
@Nullable Object... args) throws Throwable {
// Because the service interface might not be public, we need to use a MethodHandle lookup
// that ignores the visibility of the declaringClass.
Constructor<Lookup> constructor = Lookup.class.getDeclaredConstructor(Class.class, int.class);
constructor.setAccessible(true);
return constructor.newInstance(declaringClass, -1 /* trusted */)
.unreflectSpecial(method, declaringClass)
.bindTo(object)
.invokeWithArguments(args);
}
}
<------------3.Android这个类---------------------------->
// 线程切换是通过一开始创建Retrofit对象时,调用Builder()时,Platform在检测到运行环境是Android时进行创建的
// 采用适配器模式
static class Android extends Platform {
@Override public Executor defaultCallbackExecutor() {
// 返回一个默认的回调方法执行器
// 该执行器作用:切换线程(子->>主线程),并在主线程(UI线程)中执行回调方法
MainThreadExecutor()
return new MainThreadExecutor();
}
// 创建默认的网络请求适配器工厂
// 该默认工厂生产的 adapter 会使得Call在异步调用时在指定的 Executor 上执行回调
// 在Retrofit中提供了四种CallAdapterFactory: ExecutorCallAdapterFactory(默认)、GuavaCallAdapterFactory、Java8CallAdapterFactory、RxJavaCallAdapterFactory
// 采用了策略模式
@Override CallAdapter.Factory defaultCallAdapterFactory(@Nullable Executor callbackExecutor) {
if (callbackExecutor == null) throw new AssertionError();
return new ExecutorCallAdapterFactory(callbackExecutor);
}
<------------4.MainThreadExecutor---------------------------->
static class MainThreadExecutor implements Executor {
//绑定到主线程的Handler
private final Handler handler = new Handler(Looper.getMainLooper());
@Override public void execute(Runnable r) {
// 该Handler是上面获取的与Android 主线程绑定的Handler
// 在UI线程进行对网络请求返回数据处理等操作。
handler.post(r);
}
}
}
}
//// 切换线程的流程:
// 1. 回调ExecutorCallAdapterFactory生成了一个ExecutorCallbackCall对象
//2. 通过调用ExecutorCallbackCall.enqueue(CallBack)从而调用MainThreadExecutor的execute()通过handler切换到主线程
.baseUrl(Api.APP_DOMAIN)方法
把baseurl转化成适合okhttp请求的url变量,具体如下
public Builder baseUrl(String baseUrl) {
//判空
checkNotNull(baseUrl, "baseUrl == null");
//string类型转换成HttpUrl类型
HttpUrl httpUrl = HttpUrl.parse(baseUrl);
if (httpUrl == null) {
throw new IllegalArgumentException("Illegal URL: " + baseUrl);
}
<-------看下一个类------->
return baseUrl(httpUrl);
}
上面baseUrl类
public Builder baseUrl(HttpUrl baseUrl) {
checkNotNull(baseUrl, "baseUrl == null");
//依次提取出Path的各个部分的字符串
List<String> pathSegments = baseUrl.pathSegments();
//如果baseurl不是以"/"的结尾,就会抛出异常
if (!"".equals(pathSegments.get(pathSegments.size() - 1))) {
throw new IllegalArgumentException("baseUrl must end in /: " + baseUrl);
}
this.baseUrl = baseUrl;
return this;
}
.addConverterFactory(GsonConverterFactory.create())方法
/** Add converter factory for serialization and deserialization of objects. */
public Builder addConverterFactory(Converter.Factory factory) {
//converterFactories对象是retrofit成员变量,上面有讲
//add添加了一个我们创建的factory:GsonConverterFactory
converterFactories.add(checkNotNull(factory, "factory == null"));
return this;
}
下面看一下GsonConverterFactory.create()方法
public static GsonConverterFactory create() {
//看一下以下的creat(Gson gson)方法
return create(new Gson());
}
public static GsonConverterFactory create(Gson gson) {
if (gson == null) throw new NullPointerException("gson == null");
//接下来看GsonConverterFactory(Gson gson)
return new GsonConverterFactory(gson);
}
private final Gson gson;
private GsonConverterFactory(Gson gson) {
this.gson = gson;
}
实际上:GsonConverterFactory.create()创建来一个带Gson gson的实例的GsonConverterFactory对象,然后返回给addConverterFactory()方法。
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
public Builder addCallAdapterFactory(CallAdapter.Factory factory) {
//callAdapterFactories是retrofit的成员变量,上面说过。
//作用是将factory:RxJavaCallAdapterFactory.create()添加到callAdapterFactories集合中
callAdapterFactories.add(checkNotNull(factory, "factory == null"));
return this;
}
接下来看一下RxJavaCallAdapterFactory.create()
public static RxJavaCallAdapterFactory create() {
return new RxJavaCallAdapterFactory(null, false);
}
private RxJavaCallAdapterFactory(@Nullable Scheduler scheduler, boolean isAsync) {
this.scheduler = scheduler;
this.isAsync = isAsync;
}
实际上:RxJavaCallAdapterFactory.create()创建来一个带Scheduler scheduler、boolean isAsync的实例的RxJavaCallAdapterFactory对象,然后返回给addCallAdapterFactory()方法。
.build()方法
public Retrofit build() {
//baseurl非空判断
if (baseUrl == null) {
throw new IllegalStateException("Base URL required.");
}
okhttp3.Call.Factory callFactory = this.callFactory;
//retrofit默认okhttp进行网络请求
if (callFactory == null) {
callFactory = new OkHttpClient();
}
// callbackExecutor 用于线程切换
Executor callbackExecutor = this.callbackExecutor;
if (callbackExecutor == null) {
//默认创建的是主线程的Executor
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工厂集合添加默认的调用适配器工厂
callAdapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));
//创建转换器的防御性副本。
// Make a defensive copy of the converters.
List<Converter.Factory> converterFactories =
new ArrayList<>(1 + this.converterFactories.size());
// Add the built-in converter factory first. This prevents overriding its behavior but also
// ensures correct behavior when using converters that consume all types.
//通过传入BuiltInConverters()对象配置数据转换器工厂(converterFactories)
// converterFactories是一个存放数据转换器Converter.Factory的数组
// 配置converterFactories即配置里面的数据转换器
// BuiltInConverters是一个内置的数据转换器工厂(继承Converter.Factory类)new BuiltInConverters():是为了初始化数据转换器
converterFactories.add(new BuiltInConverters());
converterFactories.addAll(this.converterFactories);
//创建Retrofit对象
return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories),
unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);
}
}
build()方法就是把Retrofit类里面的成员变量都配置完毕。
RxJavaCallAdapterFactory分析
RxJavaCallAdapterFactory是继承 abstract class Factory类的,Factory是定义在CallAdapter接口中的
CallAdapter
作用:CallAdapter将retrofit的call对象转化成java对象,retrofit中的call和okhttp的call不太一样,retrofit的call对okhttp中的call进行了封装。
具体过程:
关于coverter,他可以根据addConverterFactory进行个性化配置,如果不配置retrofit默认配置GsonConverterFactory
CallAdapter类源码
public interface CallAdapter<R, T> {
//我们所需要的接口数据解析后的类型
Type responseType();
//T类型是我们需要转换成接口的返回类型,Call:是okhttp的call
T adapt(Call<R> call);
//当我们addCallAdapterFactory里面的工厂类的时候,里面工程类需要继承Factory这个类。
abstract class Factory {
//根据接口返回类型、注解类型,得到实际需要的callAdapter
public abstract @Nullable CallAdapter<?, ?> get(Type returnType, Annotation[] annotations,
Retrofit retrofit);
protected static Type getParameterUpperBound(int index, ParameterizedType type) {
return Utils.getParameterUpperBound(index, type);
}
//获取接口数据原始类型
protected static Class<?> getRawType(Type type) {
return Utils.getRawType(type);
}
}
}
rxjava如何运作
RxJavaCallAdapterFactory:
RxJavaCallAdapterFactory实现Factory抽象类,用来提供具体的适配逻辑,然后通过addCallAdapterFactory(allAdapter.Factory factory)方法注册CallAdapte,然后调用Factory里面回调回来的get(Type returnType, Annotation[] annotations,Retrofit retrofit)方法获取CallAdapter对象,最后调用CallAdapter的adapt(Call<R> call)方法,这个方法把call请求转化成每一个平台所试用的类型
get方法
@Override
public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
//获取原始数据类型
Class<?> rawType = getRawType(returnType);
//下面判断rawType是否是rxjava类型的
boolean isSingle = rawType == Single.class;
boolean isCompletable = rawType == Completable.class;
if (rawType != Observable.class && !isSingle && !isCompletable) {
return null;
}
if (isCompletable) {
return new RxJavaCallAdapter(Void.class, scheduler, isAsync, false, true, false, true);
}
boolean isResult = false;
boolean isBody = false;
Type responseType;
if (!(returnType instanceof ParameterizedType)) {
String name = isSingle ? "Single" : "Observable";
throw new IllegalStateException(name + " return type must be parameterized"
+ " as " + name + "<Foo> or " + name + "<? extends Foo>");
}
Type observableType = getParameterUpperBound(0, (ParameterizedType) returnType);
Class<?> rawObservableType = getRawType(observableType);
if (rawObservableType == Response.class) {
if (!(observableType instanceof ParameterizedType)) {
throw new IllegalStateException("Response must be parameterized"
+ " as Response<Foo> or Response<? extends Foo>");
}
responseType = getParameterUpperBound(0, (ParameterizedType) observableType);
} else if (rawObservableType == Result.class) {
if (!(observableType instanceof ParameterizedType)) {
throw new IllegalStateException("Result must be parameterized"
+ " as Result<Foo> or Result<? extends Foo>");
}
responseType = getParameterUpperBound(0, (ParameterizedType) observableType);
isResult = true;
} else {
responseType = observableType;
isBody = true;
}
//最后会返回一个RxJavaCallAdapter的实现对象
return new RxJavaCallAdapter(responseType, scheduler, isAsync, isResult, isBody, isSingle,
false);
}
}
接下来就会调RxJavaCallAdapter里面的adapt()方法
RxJavaCallAdapter类
final class RxJavaCallAdapter<R> implements CallAdapter<R, Object> {
private final Type responseType;
private final @Nullable Scheduler scheduler;
private final boolean isAsync;
private final boolean isResult;
private final boolean isBody;
private final boolean isSingle;
private final boolean isCompletable;
RxJavaCallAdapter(Type responseType, @Nullable Scheduler scheduler, boolean isAsync,
boolean isResult, boolean isBody, boolean isSingle, boolean isCompletable) {
this.responseType = responseType;
this.scheduler = scheduler;
this.isAsync = isAsync;
this.isResult = isResult;
this.isBody = isBody;
this.isSingle = isSingle;
this.isCompletable = isCompletable;
}
@Override public Type responseType() {
return responseType;
}
@Override public Object adapt(Call<R> call) {
//被观察者,创建他的实例,将call对象和被观察进行关联
OnSubscribe<Response<R>> callFunc = isAsync
? new CallEnqueueOnSubscribe<>(call)
: new CallExecuteOnSubscribe<>(call);
OnSubscribe<?> func;
if (isResult) {
func = new ResultOnSubscribe<>(callFunc);
} else if (isBody) {
func = new BodyOnSubscribe<>(callFunc);
} else {
func = callFunc;
}
Observable<?> observable = Observable.create(func);
if (scheduler != null) {
//执行retrofit中的网络请求
observable = observable.subscribeOn(scheduler);
}
if (isSingle) {
return observable.toSingle();
}
if (isCompletable) {
return observable.toCompletable();
}
return observable;
}
}
addCallAdapterFactory总结
获取call对象,执行http请求,retrofit调用call请求,其实最终调用的是okhttp当中的call,只不过retrofit对call进行类封装,然后就可以获取到服务端返回对数据,获取到数据以后调用converter把所需要的对象转化出java对象来。
每个需要不同的适配器工厂,所以addCallAdapterFactory实现:
实现CallAdapter.Factory抽象类,然后注册到CallAdapter中,通过Factory的get方法获取CallAdapter对象,CallAdapter对象调用adapter方法,将call请求转化成每个平台所试用的对象类型。