Retrofit源码 简单浏览

Retrofit:

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, @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);
}
ServiceMethod<Object, Object> serviceMethod =
(ServiceMethod<Object, Object>) loadServiceMethod(method);
OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
return serviceMethod.adapt(okHttpCall);
}
});
}
这里用到了动态代理,这里的动态代理的作用是,你只需要声明式地写了一个接口然后它代理这个接口类,事实是并没有产生一个实际的类.
public interface APIService {

@FormUrlEncoded
@POST("/")
Call<Bean> getNewList(@HeaderMap Map<String, String> headers,
@FieldMap Map<String, String> options);
}
这是常用的方式,使用声明式地,写了一个接口,getNewList用注解表明它的请求方式,转换工厂的方法参数.
如果不用动态代理,你也可以像volley,写一个request,然后对这个类,添加一些东西,再放到线程池中去运行.这样的做法,导致你所有的类都是要继承request接口类的.
而它动态代理,ServiceMethod是生成了这个对象,然后通过它,获取注解的一些信息通过工厂,生成各种适配器.然后调用okhttp去执行.
loadServiceMethod()方法:
synchronized (serviceMethodCache) {
result = serviceMethodCache.get(method);
if (result == null) {
result = new ServiceMethod.Builder<>(this, method).build();
serviceMethodCache.put(method, result);
}
}
return result;
它缓存了ServiceMethod 对象.因为一个请求包装类,它需要解析请求的参数,转换器,适配器等.看下面的代码就知道,做的事较多.
ServiceMethod
public ServiceMethod build() {
callAdapter = createCallAdapter();
responseType = callAdapter.responseType();
responseConverter = createResponseConverter();

for (Annotation annotation : methodAnnotations) {
parseMethodAnnotation(annotation);
}

if (!hasBody) {
...
}

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);
}
这个build构建方法中,对public interface APIService这个接口里声明的一些东西进行了处理.比如参数的验证,类型推断等.
createCallAdapter又回到了retforit的:
public CallAdapter<?, ?> nextCallAdapter(@Nullable CallAdapter.Factory skipPast, Type returnType,
Annotation[] annotations) {
int start = callAdapterFactories.indexOf(skipPast) + 1;
for (int i = start, count = callAdapterFactories.size(); i < count; i++) {
CallAdapter<?, ?> adapter = callAdapterFactories.get(i).get(returnType, annotations, this);
if (adapter != null) {
return adapter;
}
}
......
}
从工厂里取,如果有适配器了.然后就可以得到返回的类型,Call<Bean>,这个用于创建数据转换器的时候用.
转换器:又回到了retrofit
retrofit.responseBodyConverter(responseType, annotations);它使用的和上面的适配器类似,从转换器工厂里取
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;
}
}
这个工厂,有几个内置的转换器,在 BuiltInConverters中.
RequestBodyConverter 请求转换器,
VoidResponseBodyConverter
StreamingResponseBodyConverter
BufferingResponseBodyConverter
ToStringConverter

创建了ServiceMethod 后,就开始调用它,然后到了callAdapter.adapt(call);这时才到具体的数据请求中.
static final class ExecutorCallbackCall<T> implements Call<T> {},这只是一个代理类.具体的是:
final class OkHttpCall<T> implements Call<T> {}这个类,一看到okhttp,就明白,这才是真正请求网络的地方.
delegate.enqueue(new Callback<T>() {}这个方法,用到了平台相关的,android里,在这里,就转为主线程了.其它部分,全部是从代理到OkHttpCall去执行的.
它与okhttp是一个公司开发的,okhttp用于替代httpurlconnection.但还是不够方便使用,而retrofit的出现,则完善了这方面的功能.它是真正面对用户的.不再需要知道,http连接,获取的具体过程了,只通过注解,声明式的编程,就完成了一个网络请求,甚至返回的结果,也使用了gson这些映射,形成了真正的面对对象了.

关于其中的动态代理:
interface Service {
void perform();
}
Service proxy = (Service) Proxy.newProxyInstance(getClass().getClassLoader(), new Class<?>[]{Service.class},
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) {
System.out.println("invoke proxy perform");
return null;
}
});
proxy.perform();
不需要实现类,只需要一个接口就行了.这边的invoke没有返回对象.



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值