设计模式:
外观模式,构建者模式,工厂模式,代理模式,适配器模式,策略模式,观察者模式
Retrofit网络通信八步骤
- 创建Retrofit实例
- 定义网络请求接口,并为接口中的方法添加注解
- 通过动态代理生成网络请求对象
- 通过网络请求适配器将网络请求对象进行平台适配
- 通过网络请求执行器,发送网络请求(call)
- 通过数据解析器解析数据
- 通过回调执行器,切换线程
- 用户在主线程处理返回结果
@GET("/user/{user}/repos")
Call<ResponseBody> find(@Path("user") String user);
//call封装了整个okhttp的请求
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com/")
.addConverterFactory(GsonConverteractory.create())
//.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build();
//动态生成代理对象
Request req = retrofit.create(Request.class);
//生成一个OKHttpCall的代理对象
Call<ResponseBody> call = req.find(“Mike”);
//返回结果
Response<ResponseBody> response = call.execute();
先看Create方法
public <T> T create(final Class<T> service) {
Utils.validateServiceInterface(service);
if (validateEagerly) {
eagerlyValidateMethods(service);
}
//重点看这里
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, 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);
}
});
}
使用了动态代理,Proxy.newProxyInstance()返回一个代理类对象。
invoke方法接收三个参数,动态代理对象、我们调用的方法、参数数组;
loadServiceMethod方法:
ServiceMethod loadServiceMethod(Method method) {
ServiceMethod result;
synchronized (serviceMethodCache) {
result = serviceMethodCache.get(method);
if (result == null) {
result = new ServiceMethod.Builder(this, method).build();
serviceMethodCache.put(method, result);
}
}
return result;
}
Build类:
public Builder(Retrofit retrofit, Method method) {
this.retrofit = retrofit;
this.method = method;
// 获取 method 中的所有注解
this.methodAnnotations = method.getAnnotations();
// 获取 method 中方法的参数类型
this.parameterTypes = method.getGenericParameterTypes();
// 获得参数的值
this.parameterAnnotationsArray = method.getParameterAnnotations();
}
build()方法主要内容
// 根据 retrofit 对象的 CallAdapterFactory 为 ServiceMethod 创建一个 callAdapter
callAdapter = createCallAdapter();
// 根据 retrofit 对象创建一个 responseConverter,默认是一个 BuildInConveter
responseConverter = createResponseConverter();
// 解析 method 的所有注解
for (Annotation annotation : methodAnnotations) {
parseMethodAnnotation(annotation);
}
所以ServiceMethod主要封装了callAdapter和responseConverter ,对注解进行了解析,对后面网络请求做准备。
看回Create方法的代码
return serviceMethod.callAdapter.adapt(okHttpCall);
最后是调用了callAdapter的adapt方法,如果我们添加了RxJava2CallAdapter,
@Override
public Object adapt(Call<R> call) {
Observable<Response<R>> responseObservable = isAsync
? new CallEnqueueObservable<>(call)
: new CallExecuteObservable<>(call);
Observable<?> observable;
if (isResult) {
observable = new ResultObservable<>(responseObservable);
} else if (isBody) {
observable = new BodyObservable<>(responseObservable);
} else {
observable = responseObservable;
}
if (scheduler != null) {
observable = observable.subscribeOn(scheduler);
}
if (isFlowable) {
return observable.toFlowable(BackpressureStrategy.LATEST);
}
if (isSingle) {
return observable.singleOrError();
}
if (isMaybe) {
return observable.singleElement();
}
if (isCompletable) {
return observable.ignoreElements();
}
return observable;
}
所以如果添加了RxJava2CallAdapter就返回observal对象。
Retrofit中还有一个Converter ,与CallAdapter一样重要,用户可以根据需求对这两个进行自由扩展。
Okhttp中服务器返回的数据源就是ResponseBody对象。所以我们的目标就是对ResponseBody进行解析:
T convert(ResponseBody value){
//do convert and return t
}
Retrofit不仅可以对ResponseBody进行转换,也可以对RequestBody进行转换;具体其内部提供了一个Convert.Factory:
abstract class Factory {
//对ResponseBody进行数据转换的转换器
public @Nullable Converter<ResponseBody, ?> responseBodyConverter(Type type,
Annotation[] annotations, Retrofit retrofit) {
return null;
}
//将未知数据转换成RequestBody的转换器
public @Nullable Converter<?, RequestBody> requestBodyConverter(Type type,
Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
return null;
}
//将未知数据转换成String类型的数据转换器
public @Nullable Converter<?, String> stringConverter(Type type, Annotation[] annotations,
Retrofit retrofit) {
return null;
}
}
开头构建Retrofit对象的
.addConverterFactory(GsonConverterFactory.create()) //添加Gson
就是用来添加Gson对象的
public static GsonConverterFactory create() {
return create(new Gson());
}
public static GsonConverterFactory create(Gson gson) {
return new GsonConverterFactory(gson);
}
class GsonConverterFactory extends Converter.Factory{
//持有一个gson对象用来讲原始数据转换成JavaBean
private final Gson gson;
private GsonConverterFactory(Gson gson) {
this.gson = gson;
}
}
具体转换过程可以看Gson原理分析。