Retrofit—Jake Wharton大神的网络请求类库,OkHttp的基础上进行二次封装,使用更加的简单和方便。关于用法在这里就不做赘述了,我们直接打开Retrofit的核心方法create(class<T> service )来做分析。
public <T> T create(final Class<T> service) {
//检测是否是interface接口,否则直接抛出异常
Utils.validateServiceInterface(service);
//接口是否有更新
if (validateEagerly) {
//更新方法Map
eagerlyValidateMethods(service);
}
//Java动态代理
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.callAdapter.adapt(okHttpCall);
}
});
}
我们看一下eagerlyValidateMethods方法,首先获取当前Android平台,然后遍历当前Interface的所有method方法,再加载
private void eagerlyValidateMethods(Class<?> service) {
Platform platform = Platform.get();
for (Method method : service.getDeclaredMethods()) {
if (!platform.isDefaultMethod(method)) {
loadServiceMethod(method);
}
}
}
loadServiceMethod加载缓存ServiceMethod,或者构建新的ServiceMethod并加入缓存serviceMethodCache
//ConcurrentHashMap并发的线程安全的HashMap
private final Map<Method, ServiceMethod<?, ?>> serviceMethodCache = new ConcurrentHashMap<>();
ServiceMethod<?, ?> loadServiceMethod(Method method) {
ServiceMethod<?, ?> result = serviceMethodCache.get(method);
if (result != null) return result;
synchronized (serviceMethodCache) {
result = serviceMethodCache.get(method);
if (result == null) {
result = new ServiceMethod.Builder<>(this, method).build();
serviceMethodCache.put(method, result);
}
}
return result;
}
ServiceMethod,封装了Interface的方法Method、注解、url、httpMethod、Headers等的类
Builder(Retrofit retrofit, Method method) {
this.retrofit = retrofit;
this.method = method;
//注解
this.methodAnnotations = method.getAnnotations();
//方法的形式参数类型
this.parameterTypes = method.getGenericParameterTypes();
//方法参数上的注解集合
this.parameterAnnotationsArray = method.getParameterAnnotations();
}
构造ServiceMethod对象
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);
}
...
...
...
return new ServiceMethod<>(this);
}
绕了一圈,我们还是回到Retrofit.create(class<T> service )来。我们看到方法直接return Proxy.newProxyInstance();在这里使用了JavaSE中的动态代理类Proxy,利用反射对方法在new InvocationHandler()的invoke(Object proxy, Method method, Object[] args)方法中进行增强及执行,其中proxy,代理对象;method,代理方法;args,代理参数。
//如果是Object的方法,直接执行
if (method.getDeclaringClass() == Object.class) {
return method.invoke(this, args);
}
//非安卓平台为true
if (platform.isDefaultMethod(method)) {
return platform.invokeDefaultMethod(method, service, proxy, args);
}
如前面的loadServiceMethod一样获取得到ServiceMethod,然后构建OkHttpCall请求并执行获得Call的数据返回。
ServiceMethod<Object, Object> serviceMethod =
(ServiceMethod<Object, Object>) loadServiceMethod(method);
OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
return serviceMethod.callAdapter.adapt(okHttpCall);
这样一个Java接口就被翻译成了OkHttpCall的可执行请求。在OkHttpCall里转换了请求,并使用Okhttp3来进行执行请求,回调Callback。
网友评论