一.Retrofit代码详解
1.使用方式
Retrofit retrofit = new Retrofit.Builder().
baseUrl("https://www.wanandroid.com/").
addConverterFactory(GsonConverterFactory.create()).
build();
//1动态代理生成代理接口代理实例
WanAndroidApi wanAndroidApi=retrofit.create(WanAndroidApi.class);
//2创建Call
Call<ProjectBeanResult> call=wanAndroidApi.getProject1();
//3进行网络请求
call.enqueue(new Callback<ProjectBeanResult>() {
@Override
public void onResponse(Call<ProjectBeanResult> call, Response<ProjectBeanResult> response) {
Log.e("tag","当前的线程"+Thread.currentThread().getName());
ProjectBeanResult projectBean = response.body();
if(projectBean != null){
Log.e("tag","success "+projectBean);
}
}
@Override
public void onFailure(Call<ProjectBeanResult> call, Throwable t) {
Log.e("tag","onFailure...... ");
}
});
代码分成重要的三步
(1)创建接口代理
WanAndroidApi wanAndroidApi=retrofit.create(WanAndroidApi.class);
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)
//调用方法的时候,生成call对象
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 serviceMethod = loadServiceMethod(method);
OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);
return serviceMethod.callAdapter.adapt(okHttpCall);
}
});
}
(2)生成call对象 ,动态代理生成Call对象
Call<ProjectBeanResult> call=wanAndroidApi.getProject1();
//这时候动态代理使用下面的方法创建Call可以分为两部分1创建ServiceMethod2创建OkHttpCall
ServiceMethod serviceMethod = loadServiceMethod(method); OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args); return serviceMethod.callAdapter.adapt(okHttpCall);
①创建ServiceMethod
// ServiceMethod生成方式,缓存到Hashmap里面
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;
}
然后看一下new ServiceMethod.Builder(this, method).build();方法
初始化1 callbackExecutor:回调执行器 2 CallAdapter 创建Call的适配器 3Converter 数据转换器4初始化请求参数,header信息
public ServiceMethod build() {
callAdapter = createCallAdapter();
responseType = callAdapter.responseType();
if (responseType == Response.class || responseType == okhttp3.Response.class) {
throw methodError("'"
+ Utils.getRawType(responseType).getName()
+ "' is not a valid response body type. Did you mean ResponseBody?");
}
responseConverter = createResponseConverter();
for (Annotation annotation : methodAnnotations) {
parseMethodAnnotation(annotation);
}
if (httpMethod == null) {
throw methodError("HTTP method annotation is required (e.g., @GET, @POST, etc.).");
}
if (!hasBody) {
if (isMultipart) {
throw methodError(
"Multipart can only be specified on HTTP methods with request body (e.g., @POST).");
}
if (isFormEncoded) {
throw methodError("FormUrlEncoded can only be specified on HTTP methods with "
+ "request body (e.g., @POST).");
}
}
int parameterCount = parameterAnnotationsArray.length;
parameterHandlers = new ParameterHandler<?>[parameterCount];
for (int p = 0; p < parameterCount; p++) {
Type parameterType = parameterTypes[p];
if (Utils.hasUnresolvableType(parameterType)) {
throw parameterError(p, "Parameter type must not include a type variable or wildcard: %s",
parameterType);
}
Annotation[] parameterAnnotations = parameterAnnotationsArray[p];
if (parameterAnnotations == null) {
throw parameterError(p, "No Retrofit annotation found.");
}
parameterHandlers[p] = parseParameter(p, parameterType, parameterAnnotations);
}
if (relativeUrl == null && !gotUrl) {
throw methodError("Missing either @%s URL or @Url parameter.", httpMethod);
}
if (!isFormEncoded && !isMultipart && !hasBody && gotBody) {
throw methodError("Non-body HTTP method cannot contain @Body.");
}
if (isFormEncoded && !gotField) {
throw methodError("Form-encoded method must contain at least one @Field.");
}
if (isMultipart && !gotPart) {
throw methodError("Multipart method must contain at least one @Part.");
}
return new ServiceMethod<>(this);
}
②创建Call对象
//先创建一个Call OkHttpCall
OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);
//然后通过适配器模式转一个下okhttpCall生成一个Call
return serviceMethod.callAdapter.adapt(okHttpCall);
final class ExecutorCallAdapterFactory extends CallAdapter.Factory {
@Override
public CallAdapter<Call<?>> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
if (getRawType(returnType) != Call.class) {
return null;
}
final Type responseType = Utils.getCallResponseType(returnType);
return new CallAdapter<Call<?>>() {
@Override
public Type responseType() {
return responseType;
}
@Override
public <R> Call<R> adapt(Call<R> call) {
return new retrofit2.ExecutorCallAdapterFactory.ExecutorCallbackCall<>(callbackExecutor, call);
}
};
}
}
}
(3)进行网络请求
call.enqueue(new Callback<ProjectBeanResult>());
//调用的是ExecutorCallbackCall的enqueue
static final class ExecutorCallbackCall<T> implements Call<T> {
final Executor callbackExecutor;
final Call<T> delegate;
ExecutorCallbackCall(Executor callbackExecutor, Call<T> delegate) {
this.callbackExecutor = callbackExecutor;
this.delegate = delegate;
}
@Override public void enqueue(final Callback<T> callback) {
if (callback == null) throw new NullPointerException("callback == null");
//delegate是OkhttpCall对象
delegate.enqueue(new Callback<T>() {
@Override public void onResponse(Call<T> call, final Response<T> response) {
//切换回调的线程执行回调方法
callbackExecutor.execute(new Runnable() {
@Override public void run() {
if (delegate.isCanceled()) {
// Emulate OkHttp's behavior of throwing/delivering an IOException on cancellation.
callback.onFailure(ExecutorCallAdapterFactory.ExecutorCallbackCall.this, new IOException("Canceled"));
} else {
callback.onResponse(ExecutorCallAdapterFactory.ExecutorCallbackCall.this, response);
}
}
});
}
@Override public void onFailure(Call<T> call, final Throwable t) {
callbackExecutor.execute(new Runnable() {
@Override public void run() {
callback.onFailure(ExecutorCallAdapterFactory.ExecutorCallbackCall.this, t);
}
});
}
});
}
}
}
//OkHttpCall的enqueue 很简单就是分为两步1创建Okhttp的call2用Okhttp进行请求
@Override public void enqueue(final Callback<T> callback) {
if (callback == null) throw new NullPointerException("callback == null");
okhttp3.Call call;
Throwable failure;
synchronized (this) {
if (executed) throw new IllegalStateException("Already executed.");
executed = true;
call = rawCall;
failure = creationFailure;
if (call == null && failure == null) {
try {
//1创建okhttp的Call,
call = rawCall = createRawCall();
} catch (Throwable t) {
failure = creationFailure = t;
}
}
}
if (canceled) {
call.cancel();
}
//okhttp的Call请求网络
call.enqueue(new okhttp3.Callback() {
@Override public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse)
throws IOException {
Response<T> response;
try {
response = parseResponse(rawResponse);
} catch (Throwable e) {
callFailure(e);
return;
}
callSuccess(response);
}
});
}
//创建okhttp Call的过程,通过serviceMethod 生成Request,通过callFactory生成Okhttp的Call
//serviceMethod 就是干这个用的
private okhttp3.Call createRawCall() throws IOException {
Request request = serviceMethod.toRequest(args);
okhttp3.Call call = serviceMethod.callFactory.newCall(request);
if (call == null) {
throw new NullPointerException("Call.Factory returned null.");
}
return call;
}
使用静态代理ExecutorCallbackCall(代理类)真实调用的是OkhttpCall的方法,okhttpCall方法执行完成之后,用回调的线程池执行回调操作
2.总结
先构建Retrofit对象,通过构造者模式构建,然后通过动态代理构建出来代理的接口,然后调用代理接口的请求方法生成Call,主要就是构造ServiceMethod对象,里面包含1 callbackExecutor:回调执行器 2 CallAdapter 创建Call的适配器 3Converter 数据转换器4初始化请求参数,header信息,然后通过ServiceMethod对象构造OkHttpCall的Call,然后通过这个call发送网络请求,请求过程先通过ServiceMethod(也就是应用新建接口生初始化的注释的的那些配置,通过这些生成请求的参数)生成Okhttp的call,然后发起网络请求,然后通过Converter数据解析器解析数据,然后切换到回调线程池里面回调执行方法
3.问题总结
(1)Retrofit如果将interface转成网络请求的?
通过动态代理,首先将接口里面的注释信息的参数解析出来,生成url,请求信息等参数封装到ServiceMethod里面,然后通过ServiceMethod对象构造出来Call请求
(2)Retrofit的Converter机制如何实现?
通过addConverterFactory(GsonConverterFactory.create())添加一个数据转换器
responseConverter = createResponseConverter();
private Converter<ResponseBody, T> createResponseConverter() {
Annotation[] annotations = method.getAnnotations();
try {
return retrofit.responseBodyConverter(responseType, annotations);
} catch (RuntimeException e) { // Wide exception range because factories are user code.
throw methodError(e, "Unable to create converter for %s", responseType);
}
}
public <T> Converter<ResponseBody, T> responseBodyConverter(Type type, Annotation[] annotations) {
return nextResponseBodyConverter(null, type, annotations);
}
public <T> Converter<ResponseBody, T> nextResponseBodyConverter(Converter.Factory skipPast,
Type type, Annotation[] annotations) {
checkNotNull(type, "type == null");
checkNotNull(annotations, "annotations == null");
int start = converterFactories.indexOf(skipPast) + 1;
for (int i = start, count = converterFactories.size(); i < count; i++) {
Converter<ResponseBody, ?> converter =
converterFactories.get(i).responseBodyConverter(type, annotations, this);
//如果这个转换器返回的不为空就是用这个
if (converter != null) {
//noinspection unchecked
return (Converter<ResponseBody, T>) converter;
}
}
重要的方法是
Converter<ResponseBody, ?> converter = converterFactories.get(i).responseBodyConverter(type, annotations, this); //如果这个转换器返回的不为空就是用这个 if (converter != null) { //noinspection unchecked return (Converter<ResponseBody, T>) converter; }
判断注册的所有的ConverterFactores 能不是转化成Convert,是通过type这里type就是你接口的返回值ProjectBean.callss,判断能不能处理这个类,能处理就使用这个工厂创建的Convert
@GET("project/tree/json")
public Call<ProjectBean> getProject();
//默认的数据格式转换器的工厂,从代码看的出来返回值是ResponseBody才能处理。
final class BuiltInConverters extends Converter.Factory {
@Override
public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations,
Retrofit retrofit) {
if (type == ResponseBody.class) {
if (Utils.isAnnotationPresent(annotations, Streaming.class)) {
return StreamingResponseBodyConverter.INSTANCE;
}
return BufferingResponseBodyConverter.INSTANCE;
}
if (type == Void.class) {
return VoidResponseBodyConverter.INSTANCE;
}
return null;
}
遍历所有的自定义ConvertersFactory的list,然后判断每个Factory能处理ProjectBea.class(也就是接口返回的参数),来判断能不能使用这个转换器,不能就返回空,继续遍历下一个。
4.使用的设计模式
(1)建造者模式
Refrofit和ServiceMethod对象的创建,将对象的创建和表示(内部实现)分离,调用者不用知道复杂的创建过程
(2)外观模式
ServiceMethod的build方法,使用了多种对象的的方法,统一封装到build里面ServiceMethod是门面角色。
(3)动态代理
接口类的创建,根据接口类动态构建一个接口的实现类
WanAndroidApi wanAndroidApi=retrofit.create(WanAndroidApi.class);
(4)静态代理
call.enqueue(new Callback<ResponseBody>());
发起请求的时候,静态代理类是ExecutorCallAdapterFactory,真实使用的是OkhttpCall,然后执行完回调到静态代理类里面,切换到回调线程池操作
(5)工厂模式
Convert和CallAdapter的是实现
(6)适配器模式
CallAdapter生成Call的过程
//先创建一个Call OkHttpCall
OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);
//然后通过适配器模式转一个下okhttpCall生成一个Call
return serviceMethod.callAdapter.adapt(okHttpCall);
final class ExecutorCallAdapterFactory extends CallAdapter.Factory {
@Override
public CallAdapter<Call<?>> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
if (getRawType(returnType) != Call.class) {
return null;
}
final Type responseType = Utils.getCallResponseType(returnType);
return new CallAdapter<Call<?>>() {
@Override
public Type responseType() {
return responseType;
}
@Override
public <R> Call<R> adapt(Call<R> call) {
return new retrofit2.ExecutorCallAdapterFactory.ExecutorCallbackCall<>(callbackExecutor, call);
}
};
}
}
}